淺談微信小程序之(zhī)sku屬性選擇思路 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 小程序相關 >

淺談微信小程序之(zhī)sku屬性選擇思路

發表時(shí)間:2021-5-11

發布人(rén):融晨科技

浏覽次數:59

寫在(zài)前面

??在(zài)電商平台,sku屬性選擇是(shì)産品模塊中的(de)一個(gè)常見問題。其實,解決這(zhè)個(gè)問題并不(bù)難,關鍵是(shì)要(yào / yāo)理清自己的(de)思路,将這(zhè)個(gè)大(dà)問題拆分成幾個(gè)小問題,再逐一擊破就(jiù)好了(le/liǎo)。寫這(zhè)篇文章一來(lái)是(shì)對前段時(shí)間的(de)小程序sku屬性選擇做個(gè)總結,二來(lái)是(shì)希望放在(zài)網上(shàng)能幫助到(dào)大(dà)家。掘金上(shàng)的(de)内容都系本人(rén)原創,如需轉載請注明出(chū)處,感謝!

需求分析及解決思路

??其實我個(gè)人(rén)更傾向于(yú)将這(zhè)個(gè)問題拆分爲(wéi / wèi)如下三個(gè)小問題:

需求1:sku頁面的(de)渲染

??在(zài)商品列表頁,點擊不(bù)同的(de)産品,會根據不(bù)同的(de)産品id請求産品詳情接口,跳轉到(dào)對應的(de)産品詳情頁面。在(zài)産品詳情頁面,點擊加入購物車按鈕,會彈出(chū)産品的(de)sku頁面。

??某個(gè)産品的(de)産品詳情請求結果如下所示:

{data: {id: 246, name: "Sling Cosmetic Bags dsfsad測試",…}}
data: {id: 246, name: "Sling Cosmetic Bags dsfsad測試",…}
color_image: "https://assets.forucdn.com/basics/DD-W/j5tB2xyie4maeMWKboYDuOseOgz2Jar8kIZQE1u1.jpeg"
description: "<p>* EVA Flexibility&nbsp;soles with&nbsp;cross&nbsp;&nbsp;performance&nbsp;design&nbsp;for sneaker shoes&nbsp;&nbsp;</p><p>* Mesh&nbsp;-knit fabric&nbsp;upper lining construction with EVA padded insoles</p><p>* Complete with 4 eyelets and a lace up closure for a classic look</p><p>* Perfect for every season, wear them all year round</p>"
id: 246
images: ["https://appfiles.forucdn.com/samples/1/0/Z8-1-20210428091333-X41yFkML.jpg",…]
lowest_price: "9.99"
merchant: {id: 1, code: "HCFW", name: "迪摩信息有限公司", address: "拉薩西峰區",…}
address: "拉薩西峰區"
code: "HCFW"
id: 1
name: "迪摩信息有限公司"
thumb: "https://appfiles.forucdn.com/avatars/5/20210426151158-T6UCoTjYJ6.jpeg"
name: "Sling Cosmetic Bags dsfsad測試"
size_image: "https://appfiles.forucdn.com/testing/admin/basics/Z8/OyrsoiMFpUNYeP8eWhZdHfCsQqPsKYDHGtYi2KYb.jpg"
status: "active"
type: "public"
variants: [{id: 3795, price: "9.99", color: "白色", gender: "通用", size: "通用-均碼"},…]
0: {id: 3795, price: "9.99", color: "白色", gender: "通用", size: "通用-均碼"}
1: {id: 3796, price: "66.66", color: "富貴色", gender: "男士", size: "男士-38"}
2: {id: 3797, price: "34.56", color: "黃色", gender: "通用", size: "通用-41"}
3: {id: 3798, price: "34.56", color: "黃色", gender: "通用", size: "通用-42"}
4: {id: 3799, price: "34.56", color: "綠色", gender: "通用", size: "通用-41"}
5: {id: 3800, price: "34.56", color: "綠色", gender: "通用", size: "通用-42"}
6: {id: 3801, price: "12.34", color: "測試色", gender: "通用", size: "通用-測試均碼"}
7: {id: 3802, price: "100.00", color: "黑色", gender: "男士", size: "男士-37"}
8: {id: 3803, price: "31.23", color: "dsad", gender: "男士", size: "男士-323"}
9: {id: 3804, price: "99.99", color: "測試", gender: "通用", size: "通用-41"}
10: {id: 3805, price: "99.99", color: "測試", gender: "通用", size: "通用-42"}
11: {id: 3806, price: "99.99", color: "測試", gender: "通用", size: "通用-43"}
複制代碼

??下圖是(shì)對應産品的(de)詳情頁面:

????????

??下圖是(shì)根據産品詳情接口的(de)請求結果,渲染出(chū)的(de)對應産品的(de)sku頁面:

??????????

解決思路:

  • 技術選型: 原生微信小程序MINA框架 + Vant Weapp

  • 組件化的(de)開發思想:

??1. 産品詳情頁分爲(wéi / wèi)兩個(gè)組件: 産品詳情組件和(hé / huò)底部導航組件。其中,底部導航組件又分爲(wéi / wèi)底部導航工具組件以(yǐ)及産品sku組件;

??2. 在(zài)底部導航組件中,爲(wéi / wèi)加入購物車按鈕添加點擊事件,使用有贊提供的(de)Popup彈出(chū)層組件編寫産品sku組件,并使用一個(gè)變量用于(yú)控制彈出(chū)層的(de)顯示與隐藏。同時(shí)可以(yǐ)在(zài)彈出(chū)層組件的(de)關閉回調中做一些初始化操作,在(zài)後續的(de)需求中會具體提到(dào)需要(yào / yāo)處理的(de)初始化操作。

  • 産品sku組件的(de)渲染:

??1. 根據産品詳情接口的(de)請求結果,使用萬能的(de)flex和(hé / huò)有贊提供的(de)步進器組件布局。

??2.需要(yào / yāo)特别注意顔色和(hé / huò)尺碼分類下的(de)按鈕渲染。觀察詳情接口返回的(de)variants數據不(bù)難發現,返回的(de)顔色和(hé / huò)尺寸數據有一部分是(shì)重合的(de)。所以(yǐ),不(bù)能直接對返回的(de)數據進行循環渲染。需要(yào / yāo)對返回的(de)數據做去重處理,否則顯示在(zài)顔色和(hé / huò)尺寸分類下的(de)部分數據會存在(zài)數據重疊的(de)情況,這(zhè)顯然是(shì)不(bù)合理的(de)。 比如,variants的(de)第10到(dào)第12條數據,測試這(zhè)個(gè)顔色就(jiù)重複了(le/liǎo)兩次。variants的(de)第4、6、11條數據,通用-42這(zhè)個(gè)尺碼就(jiù)重複了(le/liǎo)兩次。

<view class="attribute-warp">
    顔色
</view>
<view class="flex-button-warp stepper-warp">
    <van-button  
        wx:for="{{colors}}"
        wx:key="id" 
        custom-class="color {{selectedColorId === item.id ? 'selected' : '' }}"
        bindtap="handleColorClicked"
        data-color="{{item}}"
        disabled = "{{!m1.hasTag(availableColorArray, item.color)}}"
    >
        {{item.color}}
    </van-button>       
</view> 
複制代碼
//監聽傳入的(de)product數據,如果詳情接口請求成功,且能夠拿到(dào)詳情數據,則使用集合過濾重複的(de)顔色分類屬性
  properties: {
    product: {
      type: Object,
      observer: function (data) {
        if(Object.keys(data).length > 0) {
          this.onClose()
          const colors = Array.from(new Set(this.data.product.variants.map(item => item.color))).map((color, index) => ({
            color,
            id: index
          }))
          this.setData({
            colors
          })
        }
      }
    }
  }
複制代碼

需求2:顯示已選産品的(de)屬性

??這(zhè)個(gè)小需求其實由三部分組成,都是(shì)在(zài)點擊時(shí)觸發:

??1. 顯示已選産品的(de)分類屬性(點擊時(shí)觸發):

??如果沒有選擇産品的(de)分類屬性,提示語爲(wéi / wèi)請選擇産品屬性;如果選擇了(le/liǎo)産品的(de)分類屬性,則将選擇的(de)産品分類屬性在(zài)産品sku組件中顯示出(chū)來(lái)。

??????????


?????????

??解決思路:

??既然是(shì)分不(bù)同條件顯示已選産品的(de)分類屬性,最容易想到(dào)的(de)自然是(shì)MINA框架裏面的(de)wx:if和(hé / huò)wx:else。于(yú)是(shì)可以(yǐ)設定判斷條件,隻要(yào / yāo)兩個(gè)分類屬性都沒有被選中,就(jiù)提示請選擇産品屬性,否則顯示已選産品的(de)分類屬性。那麽如何獲取按鈕裏面的(de)值呢?其實隻需要(yào / yāo)在(zài)産品分類屬性的(de)點擊事件中,通過自定義屬性傳入當前點擊的(de)對象,再獲取裏面的(de)值顯示到(dào)産品sku上(shàng)就(jiù)可以(yǐ)了(le/liǎo)。

<view class="message">
    <text wx:if="{{ selectedColor === '' && selectedSize === ''}}">請選擇産品屬性</text>
    <text wx:else>已選屬性: {{selectedColor}} {{selectedSize}}</text>
</view>
複制代碼

??2. 顯示已選産品的(de)價格屬性(點擊時(shí)觸發):

??如果沒有選擇産品的(de)分類屬性或者選擇的(de)分類屬性隻有顔色屬性或者尺碼屬性,顯示的(de)産品價格爲(wéi / wèi)返回的(de)産品詳情接口中的(de)lowest_price字段;如果選中的(de)分類屬性包含了(le/liǎo)顔色屬性和(hé / huò)尺碼屬性,則會在(zài)返回的(de)産品詳情接口中的(de)variants對象數組中去查找對應分類屬性。如果能夠找到(dào)對應分類屬性的(de)價格,則返回相應的(de)價格,否則會報價格字段不(bù)存在(zài)的(de)錯誤。因此需要(yào / yāo)做點擊分類屬性的(de)屬性關聯,這(zhè)個(gè)會在(zài)需求3中解決。

??解決思路:

??邏輯是(shì)這(zhè)樣的(de):監聽傳入的(de)product數據,隻要(yào / yāo)接收到(dào)了(le/liǎo)這(zhè)個(gè)數據或者彈出(chū)層被關閉的(de)時(shí)候,就(jiù)立刻初始化currentPrice 的(de)值,并将product.lowest_price的(de)值賦給currentPrice 。在(zài)産品分類屬性的(de)點擊事件中,判斷産品顔色分類屬性和(hé / huò)尺寸分類屬性是(shì)否都有被選中。如果沒有,則顯示返回的(de)産品詳情接口中的(de)lowest_price字段;如果都有被選中,則在(zài)variants中去查找選中分類屬性對應的(de)價格,如果找不(bù)到(dào)就(jiù)會報價格字段不(bù)存在(zài)的(de)錯誤。因此需要(yào / yāo)做點擊分類屬性的(de)屬性關聯,這(zhè)個(gè)會在(zài)需求3中解決。

<view class="product-price-warp">
    <view></view>
    <view class="product-price">{{ currentPrice }}</view>
</view>
複制代碼

??3. 切換不(bù)同分類屬性的(de)邏輯(點擊時(shí)觸發):

??拿點擊顔色分類屬性舉栗子(zǐ)。點擊顔色分類屬性之(zhī)前,其實可以(yǐ)分爲(wéi / wèi)三種情況(最後有兩種情況結果一樣,可以(yǐ)歸并爲(wéi / wèi)一類):

  • 還沒有任何顔色分類屬性被選中,此時(shí)點擊會直接激活選中顔色分類屬性的(de)樣式;

??????????

  • 有顔色分類屬性被選中且選中的(de)顔色分類屬性和(hé / huò)要(yào / yāo)點擊的(de)顔色分類屬性一緻,此時(shí)點擊會取消激活的(de)顔色分類屬性樣式;

??????????

  • 有顔色分類屬性被選中且選中的(de)顔色分類屬性和(hé / huò)要(yào / yāo)點擊的(de)顔色分類屬性不(bù)一緻,此時(shí)點擊會取消之(zhī)前激活的(de)顔色分類屬性樣式,并激活當前選中顔色分類屬性的(de)樣式。

??????????

??解決思路: 舉選擇顔色分類屬性的(de)栗子(zǐ)來(lái)說(shuō),可以(yǐ)使用一個(gè)變量判斷當前顔色分類屬性是(shì)否被選中,以(yǐ)及當前選中的(de)顔色分類屬性對應的(de)id。這(zhè)樣就(jiù)可以(yǐ)和(hé / huò)當前點擊的(de)對象的(de)id做比較,從而(ér)處理不(bù)同的(de)判斷邏輯。這(zhè)也(yě)是(shì)爲(wéi / wèi)什麽在(zài)需求1中重構詳情接口返回的(de)數據時(shí),除了(le/liǎo)取分類屬性名外,還要(yào / yāo)爲(wéi / wèi)它們分配id的(de)原因。當然,在(zài)最後關閉彈出(chū)層的(de)回調中,需要(yào / yāo)重置所選顔色分類屬性的(de)文字和(hé / huò)id、所選尺碼分類屬性的(de)文字和(hé / huò)id。

handleColorClicked(e) {
  //此處如果不(bù)使用if條件判斷,按鈕依然可以(yǐ)點擊
  if (!this.data.availableColorArray.includes(e.currentTarget.dataset.color.color)) return
  //比較當前選中對象的(de)id和(hé / huò)當前點擊對象的(de)id
  //1.如果selectedSizeId === -1,則表明當前沒有顔色分類屬性被選中。此時(shí)點擊需要(yào / yāo)将當前點擊對象的(de)id和(hé / huò)值傳過去,傳id是(shì)爲(wéi / wèi)了(le/liǎo)進行下一次比較,傳值是(shì)爲(wéi / wèi)了(le/liǎo)顯示已選産品的(de)分類屬性。
  //2.如果選中的(de)顔色分類屬性id和(hé / huò)當前點擊對象的(de)id不(bù)一緻。此時(shí)點擊除了(le/liǎo)會取消選中的(de)顔色分類屬性,還會激活當前選中顔色分類的(de)樣式(第一種情況和(hé / huò)第二種情況是(shì)一樣的(de))。
  //3.如果選中顔色分類屬性的(de)id和(hé / huò)當前點擊對象的(de)id一緻。此時(shí)點擊會取消選中的(de)顔色分類屬性,相當于(yú)清空選中的(de)顔色分類屬性。
  if(this.data.selectedColorId.length === 0 || this.data.selectedColorId !== e.currentTarget.dataset.color.id) {
    const availableSizeArray = this.data.product.variants.filter(item => item.color === e.currentTarget.dataset.color.color).map(item => item.size)
    this.setData({
      selectedColorId: e.currentTarget.dataset.color.id,
      selectedColor: e.currentTarget.dataset.color.color,
      availableSizeArray
    })
  } else if(this.data.selectedColorId === e.currentTarget.dataset.color.id) {
    const availableSizeArray = this.data.sizes.map(item => item.size)
    this.setData({
      selectedColorId: -1,
      selectedColor: '',
      availableSizeArray
    })
  }
  this.setSelectedPrice()
}
複制代碼

需求3:處理點擊不(bù)同分類按鈕的(de)屬性關聯問題

??點擊産品的(de)顔色分類屬性,會篩選産品的(de)尺碼分類屬性,可用的(de)顯示,禁用的(de)灰顯且不(bù)可點擊;取消選擇對應的(de)顔色分類屬性後,産品的(de)尺碼分類屬性會全部恢複爲(wéi / wèi)可用狀态。點擊産品的(de)尺寸分類屬性也(yě)是(shì)同樣一個(gè)道(dào)理,所以(yǐ)需要(yào / yāo)爲(wéi / wèi)點擊不(bù)同的(de)分類按鈕做屬性關聯。

??解決思路:

??以(yǐ)點擊顔色分類屬性舉例,聊一聊産品尺碼分類屬性的(de)篩選原則。點擊顔色分類屬性後, 需要(yào / yāo)在(zài)産品的(de)variants數據中,找到(dào)包含當前顔色分類屬性的(de)variant的(de)size。這(zhè)一個(gè)或多個(gè)size就(jiù)是(shì)點擊顔色分類屬性後當前可用的(de)size屬性集,取反就(jiù)是(shì)禁用的(de)size屬性集。因爲(wéi / wèi)在(zài)需求2中已經粘貼了(le/liǎo)點擊事件的(de)代碼邏輯,此處就(jiù)不(bù)再粘貼。

??這(zhè)裏有兩處地(dì / de)方需要(yào / yāo)特别注意:1.使用van-button循環遍曆分類數據後,disabled屬性的(de)禁用原則是(shì)先篩選出(chū)可用的(de)屬性集然後取反。如果先對當前點擊的(de)color屬性取反,再通過可用的(de)color屬性集選取禁用的(de)size屬性集,可能會造成禁用的(de)size屬性集中包含當前點擊的(de)color屬性對應的(de)可用的(de)size屬性集;2.由于(yú)微信小程序不(bù)支持在(zài)函數中傳參,因此在(zài)禁用條件中需要(yào / yāo)使用wxs語言來(lái)判斷,不(bù)能使用!availableColorArray.includes(item.color)判斷。

// wxs不(bù)支持es6語法
//使用兩個(gè)逗号的(de)原因是(shì)在(zài)于(yú)可能會有名字包含測試和(hé / huò)測試色(一個(gè)顔色包含另外一個(gè)顔色的(de)名稱)這(zhè)類情況
//可以(yǐ)對數組循環遍曆,判斷名字是(shì)否一樣,如果一樣,就(jiù)返回true
function hasTag(tags, name) {
  var testStr = ',' + tags.join(',') + ',' 
  return testStr.indexOf(',' + name + ',') != -1
}

// 導出(chū)
module.exports = {
  hasTag: hasTag
}
複制代碼
<view class="attribute-warp">
    顔色
</view>
<view class="flex-button-warp stepper-warp">
    <van-button  
        wx:for="{{colors}}"
        wx:key="id" 
        custom-class="color {{selectedColorId === item.id ? 'selected' : '' }}"
        bindtap="handleColorClicked"
        data-color="{{item}}"
        disabled = "{{!m1.hasTag(availableColorArray, item.color)}}"
    >
        {{item.color}}
    </van-button>       
</view> 
複制代碼

代碼整合

?utils\helper.wxs:

// 不(bù)支持es6語法
function hasTag(tags, name) {
  var testStr = ',' + tags.join(',') + ',' 
  return testStr.indexOf(',' + name + ',') != -1
}

// 導出(chū)
module.exports = {
  hasTag: hasTag
}
複制代碼

?components\common\popup\index.wxml:

<wxs
  src="../../../utils/helper.wxs"
  module="m1"
/>
<van-popup
  closeable
  show="{{ visible }}"
  position="bottom"
  custom-class="popup"
  bind:close="onClose"
>
    <view class="flex-warp">
        <view class="product-picture">
            <base-image
                width="182rpx"
                height="182rpx"
                class="product-image"
                src="{{product.images[0]}}"
            /> 
        </view>
        <view class="product-explain">
            <view class="product-price-warp">
                <view></view>
                <view class="product-price">{{ currentPrice }}</view>
            </view>
            <view class="message">
                <text wx:if="{{ selectedColor === '' && selectedSize === ''}}">請選擇産品屬性</text>
                <text wx:else>已選屬性: {{selectedColor}} {{selectedSize}}</text>
            </view>
        </view>    
    </view> 
    <view class="attribute-warp">
        顔色
    </view>
    <view class="flex-button-warp stepper-warp">
        <van-button  
            wx:for="{{colors}}"
            wx:key="id" 
            custom-class="color {{selectedColorId === item.id ? 'selected' : '' }}"
            bindtap="handleColorClicked"
            data-color="{{item}}"
            disabled = "{{!m1.hasTag(availableColorArray, item.color)}}"
        >
            {{item.color}}
        </van-button>       
    </view> 
    <view class="attribute-warp">
        尺碼
    </view>
    <view class="flex-button-warp stepper-warp">
        <van-button  
            wx:for="{{sizes}}"
            wx:key="id" 
            custom-class="color {{selectedSizeId === item.id ? 'selected' : '' }}"
            bindtap="handleSizeClicked"
            data-size="{{item}}"
            disabled = "{{!m1.hasTag(availableSizeArray, item.size)}}"
        >
            {{item.size}}
        </van-button>    
    </view> 
    <view class="attribute-warp">
        數量
    </view>
    <view class="stepper-warp">
        <van-stepper 
            max="10000"
            value="{{ value }}" 
            async-change 
            bind:change="onChange" 
            input-class="stepper-input"
            plus-class="stepper-operation"
            minus-class="stepper-operation"
        />
    </view>
    <view bindtap="handleConfirmed" class="confirm-button">确定</view>
</van-popup>
複制代碼

?components\common\popup\index.wxss:

.popup {
    background: #FFFFFF;
    box-shadow: 0px -4px 8px 0px rgba(0, 0, 0, 0.06);
    border-radius: 20px 20px 0px 0px;
}

.flex-warp {
    margin: 41rpx 17rpx 51rpx 32rpx;
    display: flex;
}

.product-expalin {
    display: flex;
    flex-direction: column;
    margin-left: 17rpx;
}
.product-price-warp {
    display: flex;
    margin-top: 39rpx;
    margin-bottom: 36rpx;
    font-size: 34rpx;
    font-weight: bold;
    color: #FA5151;
}
.message {
    font-size: 30rpx;
    color: #7A7A7A;
}
.attribute-warp {
    font-size: 30rpx;
    color: #181818;
    margin: 47rpx 0 20rpx 33rpx;
}
.confirm-button {
    margin-top: 62rpx;
    height: 80rpx;
    color: #fff;
    line-height: 80rpx;
    text-align: center;
    font-size:30rpx;
    background: #FA5151;
}
.stepper-input {
    width: 166rpx;
    height: 80rpx;
    font-size: 30rpx;
    color: #181818;
}
.stepper-operation {
    width: 87rpx;
    height: 80rpx;
    background: #F2F2F2;
    border-radius: 10rpx;
}
.stepper-warp {
    margin-left: 30rpx;
}
.flex-button-warp {
    display: flex;
    flex-wrap: wrap;
}
.color {
    min-width: 200rpx;
    height: 80rpx;
    background: #F2F2F2;
    border-radius: 40rpx;
    font-size: 30rpx;
    color: #181818;
    text-align: center;
    line-height: 80rpx;
    margin: 20rpx 10rpx 0 0;
}
.product-explain {
    margin-left: 17rpx;
}
.selected {
    background: #FFFFFF;
    border: 2rpx solid #181818;
}
複制代碼

?components\common\popup\index.js:

Component({
  /**
   * 組件的(de)屬性列表
   */
  properties: {
    product: {
      type: Object,
      observer: function (data) {
        if(Object.keys(data).length > 0) {
          this.onClose()
          const colors = Array.from(new Set(this.data.product.variants.map(item => item.color))).map((color, index) => ({
            color,
            id: index
          }))
          const sizes = Array.from(new Set(this.data.product.variants.map(item => item.size))).map((size, index) => ({
            size,
            id: index
          }))
          this.setData({
            colors,
            sizes
          })
        }
      }
    },
    visible: {
      type: Boolean
    }
  },
  /**
   * 組件的(de)初始數據
   */
  data: {
    value: 1,
    selectedColor: '',
    selectedSize: '',
    currentPrice: 100,
    colors: {},
    sizes: {},
    selectedColorId: -1,
    selectedSizeId: -1,
    availableSizeArray: [],
    availableColorArray: []
  },
  /**
   * 組件的(de)方法列表
   */
  methods: {
    handleConfirmed() {
      this.setData({
        value: 1
      })     
      if(this.data.selectedColor !== '' && this.data.selectedSize !== '') {
        //全部選中且校驗成功時(shí)調用
        this.onClose()
        wx.showToast({
          title: '加入購物車成功',
          icon: 'success',
          duration: 2000
        })
      } else {
        //未全部選中時(shí)調用
        wx.showToast({
          title: '請選擇商品屬性',
          icon: 'none',
          duration: 2000
        }); 
      }
    },
    onChange(event) {
      this.setData({
        value: event.detail
      })
    },
    onClose() {
      const availableSizeArray = this.data.product.variants.map(item => item.size)
      const availableColorArray = this.data.product.variants.map(item => item.color)
      this.setData({
        currentPrice: this.data.product.lowest_price,
        visible: false,
        value: 1,
        selectedColor: '',
        selectedSize: '',
        selectedColorId: -1,
        selectedSizeId: -1,
        availableSizeArray,
        availableColorArray
      })
    },
    setSelectedPrice() {
      let currentPrice
      if(this.data.selectedColor !== '' && this.data.selectedSize !== '') {
        currentPrice = this.data.product.variants.find(item => item.size === this.data.selectedSize && item.color === this.data.selectedColor).price
      } else {
        currentPrice = this.data.product.lowest_price
      }
      this.setData({
        currentPrice
      }) 
    },
    handleSizeClicked(e) {
      //此處如果不(bù)使用if條件判斷,按鈕依然可以(yǐ)點擊
      if (!this.data.availableSizeArray.includes(e.currentTarget.dataset.size.size)) return
      if(this.data.selectedSizeId === -1 || this.data.selectedSizeId !== e.currentTarget.dataset.size.id) {
        const availableColorArray = this.data.product.variants.filter(item => item.size === e.currentTarget.dataset.size.size).map(item => item.color)
        this.setData({
          selectedSizeId: e.currentTarget.dataset.size.id,
          selectedSize: e.currentTarget.dataset.size.size,
          availableColorArray
        })
      } else if(this.data.selectedSizeId === e.currentTarget.dataset.size.id) {
        const availableColorArray = this.data.colors.map(item => item.color)
        this.setData({
          selectedSizeId: -1,
          selectedSize: '',
          availableColorArray
        })
      }
      this.setSelectedPrice()
    },
    //禁用存在(zài)一對多的(de)問題,不(bù)能直接使用該禁用的(de),隻能使用未禁用的(de),然後再對未禁用的(de)進行取反
    handleColorClicked(e) {
      //此處如果不(bù)使用if條件判斷,按鈕依然可以(yǐ)點擊
      if (!this.data.availableColorArray.includes(e.currentTarget.dataset.color.color)) return
      if(this.data.selectedColorId.length === 0 || this.data.selectedColorId !== e.currentTarget.dataset.color.id) {
        const availableSizeArray = this.data.product.variants.filter(item => item.color === e.currentTarget.dataset.color.color).map(item => item.size)
        this.setData({
          selectedColorId: e.currentTarget.dataset.color.id,
          selectedColor: e.currentTarget.dataset.color.color,
          availableSizeArray
        })
      } else if(this.data.selectedColorId === e.currentTarget.dataset.color.id) {
        const availableSizeArray = this.data.sizes.map(item => item.size)
        this.setData({
          selectedColorId: -1,
          selectedColor: '',
          availableSizeArray
        })
      }
      this.setSelectedPrice()
    }
  }
})
複制代碼

?components\common\popup\index.json:

{
  "component": true,
  "usingComponents": {}
}
複制代碼


寫在(zài)最後

??由于(yú)代碼寫得比較倉促,本文的(de)代碼邏輯還是(shì)比較複雜,而(ér)且存在(zài)大(dà)量的(de)重複代碼,有時(shí)間和(hé / huò)興趣的(de)小夥伴可以(yǐ)使用組件化的(de)思想重新編寫代碼。年少輕狂,總以(yǐ)爲(wéi / wèi)天下事,無可不(bù)爲(wéi / wèi),歲月蹉跎,終感到(dào)天下人(rén)力有盡頭。年輕無知,總認爲(wéi / wèi)目光内,皆爲(wéi / wèi)好人(rén),時(shí)間流轉,終歎息社會人(rén)笑裏藏刀。社會很大(dà),人(rén)心很複雜,一路走來(lái),背最黑的(de)鐵鍋,鬧最大(dà)的(de)笑話。塞翁失馬,焉知非福,惋惜之(zhī)餘也(yě)慶幸自己遇到(dào)了(le/liǎo)這(zhè)麽好的(de)媽,希望自己能保持本心,不(bù)被社會改變。

相關案例查看更多