1. 程式人生 > >用vue寫一個商城的上貨元件(簡單易懂版,50行js實現效果)

用vue寫一個商城的上貨元件(簡單易懂版,50行js實現效果)

0、結果放前面

加個Star後,fork下來。

然後在控制檯,先輸入npm install安裝依賴,再輸入npm run dev執行檢視效果

1、先列需求

一切開發都是基於需求做的,所以需求先行,根據需求設計功能。

需求如下:

  1. 上貨商品有多個屬性類別;(例如:顏色、尺寸、型號)
  2. 每個類別有多個子屬性;(例如:白色、綠色、金色)
  3. 每個商品必然具備每個類別的其中一個子屬性;
  4. 除此之外還有額外屬性,如【庫存】、【描述】、【價格】等,每個都有;
  5. 要求屬性類別可以無限新增;
  6. 要求每個屬性類別下面的子屬性可以無限新增;
  7. 最後輸出所有組合,以及他們每個組合的額外屬性;

例如:

  1. 顏色(白色,金色),尺寸(41,42);
  2. 那麼一共有四種組合:(白色,41),(白色,42),(金色,41),(金色,42);
  3. 然後給每個組合加上價格、數量等屬性,最後用JSON格式輸出;
  4. 例如輸出以下結果:
[
  {
    '顏色': '白色',
    '尺寸': '10',
    'price': '0',
    'count': '1'
  },
  {
    '顏色': '白色',
    '尺寸': '20',
    'price': '0',
    'count': '1'
  },
  {
    '顏色': '綠色',
    '尺寸': '10',
    'price': '0',
    'count'
: '1' }, { '顏色': '綠色', '尺寸': '20', 'price': '0', 'count': '1' } ]

2、思路

由於無限可擴充套件的特性,因此模組分拆為兩部分:

  1. 負責支援無限新增功能(包括類別和類別的屬性);
  2. 根據已新增的類別和屬性,組合出列表,並將列表展示或輸出;

3、程式碼如下

由於功能類似,因此沒有寫刪除、修改功能,但思路跟新增是一致的。

加個Star後,fork下來。

然後在控制檯,先輸入npm install安裝依賴,再輸入npm run dev執行檢視效果

詳細請參考註釋:

/**
* Created by 王冬 on 2017/11/14.
* QQ: 20004604
* weChat: qq20004604
*/

<template
>
<div> <button @click='getList'>輸出結果</button> <div> 輸入分類名,然後點選【確認】按鈕新增新的分類 <input type='text' v-model='category'> <button @click='addCategory'>確認</button> </div> <template v-for='i in categoryList'> <div class='category'> <p>類別:
{{i.name}}</p> <div>屬性: <p>新增屬性名:<input type='text' v-model='i.newPropertyName'> <button @click='addToPropertyList(i)'>點選新增</button> </p> <div class='property-list'> <template v-for='pro in i.propertyList'> <div class='property'>{{pro}}</div> </template> <div class='clearfloat'></div> </div> </div> </div> </template> <p>以下是展示列表</p> <div class='show-list'> <table> <tr> <td v-for='i in categoryList'> {{i.name}} </td> <td>價格</td> <td>數量</td> </tr> <tr v-for='(val,key) in showList'> <td v-for='i in categoryList'> {{val[i.name]}} </td> <td> <input type='text' v-model="val['price']"> </td> <td> <input type='text' v-model="val['count']"> </td> </tr> </table> </div> </div> </template> <style scoped> .category { border: 1px solid #333; } .property { float: left; border: 1px solid #333; display: inline-block; } table { border-collapse: collapse; } th, td { border: 1px solid #000; } /*--清除浮動--*/ .clearfloat { width: 0; clear: both; overflow: hidden; visibility: hidden; } </style> <script> export default { data () { return { // 要新增的新類別的名字 category: '', // 類別列表 categoryList: [ { // 類別名 name: '顏色', // 類別屬性列表 propertyList: ['白色', '綠色'] }, { name: '尺寸', propertyList: ['10', '20'] }, { name: '型別', propertyList: ['衣服', '褲子'] } ] } }, computed: { // 輸出列表 showList () { let arr = [] this.toGet(arr, {}, 0, this.categoryList.length) return arr } }, methods: { // 新增一個新的類別 addCategory () { // 建立新類別 let obj = { name: this.category, propertyList: [], newPropertyName: '' } // 新增到類別列表中 this.categoryList.push(obj) this.category = '' }, // 向類別新增屬性 addToPropertyList (category) { // 在該類別的屬性裡列表裡新增新的屬性 category.propertyList.push(category.newPropertyName) category.newPropertyName = '' }, // 遞迴 getList () { console.log(this.showList) return this.showList }, // 將資料組合成列表,利用遞迴的特性 toGet (arr, obj, currentIndex, maxLength) { if (currentIndex >= maxLength) { return } this.categoryList[currentIndex].propertyList.forEach(item => { // 在組合到最後一個之前,不停的往模板物件上新增屬性 obj[this.categoryList[currentIndex].name] = item if (currentIndex === maxLength - 1) { // 組合到最後一個後,建立一個新的物件,然後放置入列表中 let result = Object.assign({}, obj) result.price = '0' result.count = '1' arr.push(result) } else { this.toGet(arr, obj, currentIndex + 1, maxLength) } }) } } } </script>