[Express+Vue 搭建電商網站] 19 畫面重構

19 畫面重構

重構頁面

重構可能會造成一些功能癱瘓,本章先著重在畫面,接下來會把功能修復,莫急莫慌莫害怕

管理後台

由於我們之前在 App 組件中已經有了共用的工具列,所以打開 src/views/admin/Index.vue 修改成

<template>
 <div>
 <div class="admin-new">
 <div class="container">
 <h1>In Admin</h1>
 <router-view/>
 </div>
 </div>
 </div>
</template>

商品列表

接著打開後台的商品組件 src/views/admin/Products.vue,將 <template> 修改成

<template>
 <div class="products">
 <el-table
 class="table"
 :data="products">
 <el-table-column
 prop="name"
 label="名稱"
 width="180">
 </el-table-column>
 <el-table-column
 prop="price"
 label="售價"
 width="180">
 </el-table-column>
 <el-table-column
 prop="manufacturer.name"
 label="製造商"
 width="180">
 </el-table-column>
 <el-table-column
 label="管理"
 width="200">
 <template slot-scope="scope">
 <el-button class="modify" type="text" size="small"><router-link :to="'/admin/edit/' + scope.row._id">修改</router-link></el-button>
 <el-button class="remove" @click="removeProduct(scope.row._id), deleteRow(scope.$index, products)" type="text" size="small">删除</el-button>
 </template>
 </el-table-column>
 </el-table>
 </div>
</template>

看起來和前台的 ProductItem 組件中表格非常相似,差在對商品物件的操作。一個是將商品加入或移出購物車,一個是刪除或修改商品。

編輯商品

打開 ProductForm 組件,在 <template> 內使用組件庫提供的 el-form 表單組件代替原本簡陋的 form 表單

<template>
 <div class="productInfo">
 <el-form class="form" ref="form" :model="model" label-width="180px">
 <el-form-item label="Name">
 <el-input v-model="model.name"></el-input>
 </el-form-item>
 <el-form-item label="Price">
 <el-input v-model="model.price"></el-input>
 </el-form-item>
 <el-form-item label="Manufacturer ">
 <el-select v-model="model.manufacturer.name" clearable placeholder="请选择制造商">
 <el-option
 v-for="manufacturer in manufacturers"
 :key="manufacturer._id"
 :label="manufacturer.name"
 :value="manufacturer.name"
 ></el-option>
 </el-select>
 </el-form-item>
 <el-form-item label="Image ">
 <el-input v-model="model.image"></el-input>
 </el-form-item>
 <el-form-item label="Description ">
 <el-input type="textarea" v-model="model.description"></el-input>
 </el-form-item>
 <el-form-item>
 <el-button v-if="isEditing" type="primary" @click="onSubmit">Update Product</el-button>
 <el-button v-else @click="onSubmit">Add Product</el-button>
 </el-form-item>
 </el-form>
 </div>
</template>

接著要解決 src/views/admin/Edit.vue 組件內傳入的 computed model 無法被編輯的問題。
理由是 input 作為受控的組件,會一直顯示 Vue 的綁定資料,輸入框內容將無法進行編輯Input 输入框。結果送出之後還是沒反應,這很正常先繼續把畫面調好,等等我們會來修復它
打開 Edit 組件,將原本在 computed 中的 model 屬性放到 data 屬性中,並移除原本在 computed 中的屬性

<template>
 <div>
 <div class="title">
 <h1>This is Admin/Edit</h1>
 </div>
 <product-form
 @save-product="updateProduct"
 :model="model"
 :manufacturers="manufacturers"
 :isEditing="true"
 ></product-form>
 </div>
</template>
<script>
import ProductForm from "@/components/products/ProductForm.vue";
export default {
 data() {
 const product = this.$store.getters.productById(this.$route.params["id"]);
 return {
 // 回傳 product 的備份,是為了在修改 product 的備份之後,在保存之前不修改本地 Vuex store 的 product 屬性
 model: { ...product, manufacturer: { ...product.manufacturer } }
 };
 },
 created() {
 const { name } = this.model;
 if (!name) {
 this.$store.dispatch("productById", {
 productId: this.$route.params["id"]
 });
 }
 if (this.manufacturers.length === 0) {
 this.$store.dispatch("allManufacturers");
 }
 },
 computed: {
 manufacturers() {
 return this.$store.getters.allManufacturers;
 },
 },
 methods: {
 updateProduct(product) {
 this.$store.dispatch("updateProduct", {
 product
 });
 }
 },
 components: {
 "product-form": ProductForm
 }
};
</script>

接著,長得跟 Edit 組件很像的 New 組件也一起重構

<template>
 <product-form @save-product="addProduct" :model="model" :manufacturers="manufacturers"></product-form>
</template>
<script>
import ProductForm from "@/components/products/ProductForm.vue";
export default {
 data() {
 return {
 model: { manufacturer: { name: "" } }
 };
 },
 created() {
 if (this.manufacturers.length === 0) {
 this.$store.dispatch("allManufacturers");
 }
 },
 computed: {
 manufacturers() {
 return this.$store.getters.allManufacturers;
 }
 },
 methods: {
 addProduct(model) {
 this.$store.dispatch("addProduct", {
 product: model
 });
 }
 },
 components: {
 "product-form": ProductForm
 }
};
</script>

編輯製造商

Products 組件類似,開啟 Manufacturers 使用 el-table 替換掉原本的表單的 <template> 部分

<template>
 <div class="manufacturers">
 <el-table class="table" :data="manufacturers">
 <el-table-column prop="name" label="製造商" width="180"></el-table-column>
 <el-table-column label="管理" width="200">
 <template slot-scope="scope">
 <el-button class="modify" type="text" size="small">
 <router-link :to="'/admin/manufacturers/edit/' + scope.row._id">修改</router-link>
 </el-button>
 <el-button
 class="remove"
 @click="removeManufacturer(scope.row._id), deleteRow(scope.$index, products)"
 type="text"
 size="small"
 >刪除</el-button>
 </template>
 </el-table-column>
 </el-table>
 </div>
</template>

接著重構 NewManufacturers 組件,一樣將 computed 的 model 換到 data 屬性中

<template>
 <manufacturer-form @save-manufacturer="addManufacturer" :model="model"></manufacturer-form>
</template>
<script>
import ManufacturerForm from "@/components/ManufacturerForm.vue";
export default {
 data() {
 return {
 model: {}
 };
 },
 methods: {
 addManufacturer(model) {
 this.$store.dispatch("addManufacturer", {
 manufacturer: model
 });
 }
 },
 components: {
 "manufacturer-form": ManufacturerForm
 }
};
</script>

緊接著重構 ManufacturerForm,和 ProductForm 組件類似,將 <template> 區塊替換成組件庫樣式

<template>
 <div class="manufacturerInfo">
 <el-form class="form" ref="form" :model="model" label-width="180px">
 <el-form-item label="Name">
 <el-input v-model="model.name"></el-input>
 </el-form-item>
 <el-form-item>
 <el-button v-if="isEditing" type="primary" @click="onSubmit">Update Manufacturer</el-button>
 <el-button v-else @click="onSubmit">Add Manufacturer</el-button>
 </el-form-item>
 </el-form>
 </div>
</template>

重構購物車

最後!重構 Cart 組件,和 ProductList 類似,兩者都用了 ProductItem 組件。一樣那句話:將 <template> 區塊替換成組件庫樣式

<template>
 <div>
 <div class="title">
 <h1>{{msg}}</h1>
 </div>
 <product-item :products="cart"></product-item>
 </div>
</template>

在這一節當中主要就是使用 element-ui 組件庫將畫面做得比較酷炫。但也造成一些功能癱瘓,當下一定很緊張,但不要緊!我們馬上就要來修復功能了!

留言