全棧之路-微信小程序-SKU開發(代碼)


  SKU開發是小程序中最難的一部分,思路在分析中已經記錄過了,這里主要看一下代碼的實現,感覺老師寫的代碼太棒了,很優雅!主要想記錄一下寫代碼的思路,對面向對象編程的實踐。

一、代碼結構的分析

1、說明幾個關鍵詞

搞清楚sku的概念,搞清楚我們抽象出來的realm組件、fence組件、cell組件以及他們對應的模型類,這里模型類放到models文件夾中

realm組件 --- fence-group.js中的FenceGroup模型

fence組件 --- fence.js中的Fence模型

cell組件 --- cell.js中Cell模型

除此之外,還有

矩陣的處理模型:matrix.js中的Matrix模型

總控制模型(負責方法的調用):judger.js中的Judger模型

sku-code處理模型:sku-code.js中的SkuCode模型

2019年12月10日11:04:41截止,可能后續還會有處理sku規格值的狀態的模型,后續再補充...

2、分析他們之間的聯系(做的圖示)

說明:

圖中所示的箭頭的流向是從用戶的角度來看,當點擊規格值進行選擇時,數據的流向

感想總結:這個結構這樣抽象出來,感覺太清晰了,彼此之前是獨立的,可擴展的,但是彼此之間是有聯系的,各司其職,哇,感覺這樣寫出來的代碼太美好了,原來寫代碼可以這么舒服,好的代碼,好的架構真的讓人耳目一新,回味無窮啊!今后奮斗的方向,寫出好的代碼,優雅而強大!

二、代碼的編寫

這也不是完整的SKU代碼,只是一部分的代碼,只是用來記錄一下整個SKU開發的代碼的結構,看一下簡單的代碼(從realm組件到cell組件),實現SKU規格值的提取(SKU狀態的確定代碼就不記錄了,太復雜了,不過之后可能記錄一下其中編碼思路),順序是按照圖示的順序(開發的過程,並不是嚴格按照這個順序進行編碼的,開發是按照從fence-group出發,細化,抽象出fence,再進一步細化,抽象出cell)  

1、cell組件

這里不考慮SKU規格值的狀態的確定,所以cell組件的代碼就相對來說特別簡單,只是來負責將規格值顯示出來(代碼中沒有樣式代碼)

 1 // index.wxml代碼
 2 <!--規格值組件-->
 3 <view bind:tap="onTap" class="container">
 4     <view class="inner-container">
 5         <text>{{cell.title}}</text>
 6     </view>
 7 </view>
 8 
 9 // index.js代碼 創建cell屬性
10 properties: {
11     cell:Object
12 },

2、cell模型(cell.js)

創建Cell類,有構造方法以及id(規格值id)和title(規格值名稱)兩個屬性

 1 class Cell{
 2     id // 規格值的主鍵id
 3     title // 規格值的名字
 4 
 5     constructor(spec){
 6         this.title = spec.value
 7         this.id = spec.value_id
 8     }
 9 }
10 
11 export {
12     Cell
13 }

3、fence組件

fence組件需要引入cell組件,需要用fence屬性來傳遞數據

 1 // index.wxml
 2 <view class="container">
 3     <!--規格名-->
 4     <view class="title">{{fence.title}}</view>
 5     <!--規格名下的所有規格值-->
 6     <view class="row-container">
 7         <block wx:for="{{fence.cells}}" wx:key="{{index}}">
 8             <!--規格值組件-->
 9             <s-cell class="cell" cell="{{item}}"></s-cell>
10         </block>
11         <view class="hr"></view>
12     </view>
13 </view>
14 
15 // index.js
16 properties: {
17     fence: Object
18 },
19 
20 // index.json
21 {
22   "component": true,
23   "usingComponents": {
24       "s-cell":"/components/cell/index"
25   }
26 }

4、fence模型(fence,js)

創建Fence類,有構造方法,cells屬性(存放一個規格名下的一組規格值),specs屬性(spu(商品)的一個確定的規格值的組合,比如:金屬灰-七龍珠-小號 S),title(規格名名稱)以及id(規格名id)以及初始化cell的方法

 1 import {Cell} from "./cell";
 2 
 3 class Fence {
 4 
 5     cells = []
 6     specs
 7     title // 規格名的名字
 8     id // 規格名的主鍵id
 9 
10     constructor(specs) {
11         this.specs = specs
12         this.title = specs[0].key
13         this.id = specs[0].key_id
14     }
15 
16     init() {
17         this._initCells()
18     }
19 
20     _initCells(){
21         this.specs.forEach(s=>{
22             // 去重判斷
23             const existed = this.cells.some(c=>{
24                 return c.id === s.value_id
25             })
26             if(existed){
27                 return
28             }
29             const cell = new Cell(s)
30             this.cells.push(cell)
31         })
32     }
33 }
34 
35 export {
36     Fence
37 }

補充說明數組(Array)中的some方法:

鏈接地址詳解:https://www.runoob.com/jsref/jsref-some.html

some() 方法用於檢測數組中的元素是否滿足指定條件(函數提供)。

some() 方法會依次執行數組的每個元素:

  • 如果有一個元素滿足條件,則表達式返回true , 剩余的元素不會再執行檢測。
  • 如果沒有滿足條件的元素,則返回false。

注意: some() 不會對空數組進行檢測。

注意: some() 不會改變原始數組。

5、realm組件(對應着fence-group.js)

realm組件需要引用fence組件,需要通過spu屬性來傳遞數據,並且需要監聽spu

 1 // index.wxml代碼
 2 <view class="container">
 3     <view>
 4         <image></image>
 5     </view>
 6     <block wx:for="{{fences}}" wx:key="{{index}}">
 7         <s-fence fence="{{item}}"></s-fence>
 8     </block>
 9     <view class="counter-container">
10         <!--<l-counter></l-counter>-->
11     </view>
12 </view>
13 
14 // index.js代碼
15     properties: {
16         spu: Object
17     },
18 
19     data: {
20         judger:Object
21     },
22 
23     observers: {
24         'spu': function (spu) {
25             if (!spu) {
26                 return
27             }
28             const fenceGroup = new FenceGroup(spu)
29             fenceGroup.initFences()
30             // judge在這里並沒有用到
31             // const judger = new Judger(fenceGroup)
32             // this.data.judger = judger
33             this.bindInitData(fenceGroup)
34         }
35     },
36     methods: {
37         bindInitData(fenceGroup) {
38             this.setData({
39                 fences:fenceGroup.fences
40             })
41         },
42     }    
43 
44 // index.json
45 {
46   "component": true,
47   "usingComponents": {
48     "s-fence":"/components/fence/index"
49   }
50 }

補充說明一下,小程序中的observer監聽函數的詳解:

組件數據字段監聽器,用於監聽 properties 和 data 的變化,參見 數據監聽器

數據監聽器鏈接地址:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/observer.html

6、fence-group模型(fence-group.js)

創建FenceGroup類,創建spu屬性、skuList屬性以及fences屬性,還有初始化的fence方法(這里用到了矩陣中的轉置方法,具體就不記錄了)

 1 import {Matrix} from "./matrix";
 2 import {Fence} from "./fence";
 3 
 4 class FenceGroup {
 5     spu
 6     skuList = []
 7     fences
 8 
 9     constructor(spu) {
10         this.spu = spu
11         this.skuList = spu.sku_list
12     }
13 
14     initFences() {
15         const matrix = this._createMatrix(this.skuList)
16         const fences = []
17         // 進行矩陣的轉置操作
18         const AT = matrix.transpose()
19         AT.forEach(r => {
20             const fence = new Fence(r)
21             fence.init()
22             fences.push(fence)
23         })
24         this.fences = fences
25     }
26 
27     _createMatrix(skuList) {
28         const m = []
29         skuList.forEach(sku => {
30             m.push(sku.specs)
31         })
32         return new Matrix(m)
33     }
34 
35 }
36 
37 export {
38     FenceGroup
39 }

說明:矩陣的思想其實在這里簡化了實現思路,可以看一下具體的矩陣是如何進行裝置操作的,可看一下百度百科中的說明:

鏈接地址:https://baike.baidu.com/item/轉置矩陣

三、重要總結

數據的流向問題在啰嗦一下:

  一切都是從商品的詳情頁面進行發起的,當用戶點擊商品的時候,跳轉到詳情頁面,用戶點擊加入購物車的功能,商品的規格信息進行顯示,初始化商品的規格信息,這里觸發了realm組件的監聽spu的方法,從而引發多米諾骨效應,從FenceGroup模型的創建,到Fence模型的創建,再到Cell模型的創建,當數據最終創建之后,在通過組件一步一步的渲染。最終呈現在用戶的面前就是可選的一組規格(當然這個功能完善之后,用戶看到的是一組選擇好的規格路徑,這里沒實現),這就是完整的一個過程,當然僅僅只是一個規格值的處理提取的過程。

 

 內容出處:七月老師《從Java后端到全棧》視頻課程

七月老師課程鏈接:https://class.imooc.com/sale/javafullstack

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM