[Vue] Vue商品管理後台範例
範例程式碼
提供一個簡單的範例,快速了解Vue如何運作。其中有使用到許多指令
,可以在後續文章內查詢。
程式碼有使用到Bootstrap5的樣式。CDN:
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/js/bootstrap.min.js" integrity="sha512-WW8/jxkELe2CAiE4LvQfwm1rajOS8PHasCCx+knHG0gBHt8EXxS6T6tJRTGuDQVnluuAvMxWF4j8SNFDKceLFg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
- html
- js
<div id="app">
<div class=p-5>
<table class="table">
<thead>
<tr>
<th>標題</th>
<th>圖片</th>
<th>銷售狀態</th>
<th>編輯</th>
</tr>
</thead>
<tbody>
<tr v-for="item in products" :key="item.id" :class="{'table-success': item.onStock}">
<td>{{ item.name }}</td>
<td>
<img :src="item.imageUrl" alt="" height="100">
</td>
<td>
<input type="checkbox" v-model="item.onStock">
</td>
<td>
<button type="button" class="btn btn-outline-primary" v-on:click="editItem(item)">修改</button>
</td>
</tr>
</tbody>
</table>
<form>
<div class="mb-3">
<label for="productName" class="form-label">產品名稱</label>
<input type="text" id="productName" class="form-control" v-model="temp.name">
</div>
<div class="mb-3">
<label for="productImage" class="form-label">產品圖片</label>
<input type="text" id="productImage" class="form-control" v-model="temp.imageUrl">
</div>
<button type="button" class="btn btn-secondary" v-on:click="confirmEdit">更新</button>
</form>
</div>
</div>
const products = [
{
id: "1",
imageUrl:
"https://images.unsplash.com/photo-1516906571665-49af58989c4e?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=300&q=80",
name: "MacBook Pro",
onStock: false
},
{
id: "2",
imageUrl:
"https://images.unsplash.com/photo-1512499617640-c74ae3a79d37?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80",
name: "iPhone",
onStock: false
}
];
const App = {
data() {
return {
products: [],
temp: {}
};
},
methods: {
editItem(item) {
this.temp = { ...item };
},
confirmEdit() {
if (!this.temp.id) {
this.temp.id = new Date().getTime();
this.temp.onStock = false;
this.products.push(this.temp);
} else {
this.products.forEach((item, i) => {
if (item.id === this.temp.id) {
this.products[i] = this.temp;
}
});
}
this.temp = {};
}
},
created() {
this.products = products;
}
};
Vue.createApp(App).mount("#app");
範例文字說明
products代表著一個外部傳入的資料,我們在一開始定義data的時候還沒有products的內容,直到created()
這個生命週期的時候才將取得的資料賦予data內的products變數。(一般來說資料可能是由非同步取得,這邊只是簡單模擬,所以直接在App外層定義資料內容。
在#app
內使用v-for
的指令將producs內的每個物件依序渲染到表格中。使用v-for的時候記得補上key值。接著綁定修改以及更新按鈕的觸發事件。
因為form表單內的雙向綁定資料只有綁定到temp內的name及imageUrl,並沒有存在id。所以我們使用id存不存在去判斷現在是更新還是新增資料。 Line:29 & Line:33(JS) 。
Line:22(html) 內,我們綁定了一個事件,該事件會將v-for目前所取出的products物件(我們命名為item)當作參數傳送到medthods內 Line:25(js) 的editItem(item)
。
因為從products內取出的每個item都是物件,會用傳參考的方式進到editItem的參數中。如果今天我們使用this.temp=item
,我們在修改form表單內的內容就會直接影響到原始資料。
為了避免這種狀況,我們可以使用展開運算符(...)
來做到淺層拷貝 (Line:26(js))
待修改
上述後台還有可以修改的地方,例如可以增加刪除的功能。另外還有發現一個問題是,今天如果點擊修改按鈕,去編輯目前的商品資料 時,將form內的產品圖片Url輸入空字串傳入,上方產品列表的圖片並不會馬上消失,而是要等到點選onstock按鈕的時候才會消失(而且仍然留有邊框)。
但是更新url成另一張圖片的時候就沒有問題。需要再研究一下