欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

淺談微信小程序之sku屬性選擇思路 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

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

淺談微信小程序之sku屬性選擇思路

發(fā)表時間:2021-5-11

發(fā)布人:葵宇科技

瀏覽次數(shù):59

寫在前面

??在電商平臺,sku屬性選擇是產(chǎn)品模塊中的一個常見問題。其實,解決這個問題并不難,關鍵是要理清自己的思路,將這個大問題拆分成幾個小問題,再逐一擊破就好了。寫這篇文章一來是對前段時間的小程序sku屬性選擇做個總結(jié),二來是希望放在網(wǎng)上能幫助到大家。掘金上的內(nèi)容都系本人原創(chuàng),如需轉(zhuǎn)載請注明出處,感謝!

需求分析及解決思路

??其實我個人更傾向于將這個問題拆分為如下三個小問題:

需求1:sku頁面的渲染

??在商品列表頁,點擊不同的產(chǎn)品,會根據(jù)不同的產(chǎn)品id請求產(chǎn)品詳情接口,跳轉(zhuǎn)到對應的產(chǎn)品詳情頁面。在產(chǎn)品詳情頁面,點擊加入購物車按鈕,會彈出產(chǎn)品的sku頁面。

??某個產(chǎn)品的產(chǎn)品詳情請求結(jié)果如下所示:

{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: "拉薩西峰區(qū)",…}
address: "拉薩西峰區(qū)"
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"}
復制代碼

??下圖是對應產(chǎn)品的詳情頁面:

????????

??下圖是根據(jù)產(chǎn)品詳情接口的請求結(jié)果,渲染出的對應產(chǎn)品的sku頁面:

??????????

解決思路:

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

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

??1. 產(chǎn)品詳情頁分為兩個組件: 產(chǎn)品詳情組件和底部導航組件。其中,底部導航組件又分為底部導航工具組件以及產(chǎn)品sku組件;

??2. 在底部導航組件中,為加入購物車按鈕添加點擊事件,使用有贊提供的Popup彈出層組件編寫產(chǎn)品sku組件,并使用一個變量用于控制彈出層的顯示與隱藏。同時可以在彈出層組件的關閉回調(diào)中做一些初始化操作,在后續(xù)的需求中會具體提到需要處理的初始化操作。

  • 產(chǎn)品sku組件的渲染:

??1. 根據(jù)產(chǎn)品詳情接口的請求結(jié)果,使用萬能的flex和有贊提供的步進器組件布局。

??2.需要特別注意顏色和尺碼分類下的按鈕渲染。觀察詳情接口返回的variants數(shù)據(jù)不難發(fā)現(xiàn),返回的顏色和尺寸數(shù)據(jù)有一部分是重合的。所以,不能直接對返回的數(shù)據(jù)進行循環(huán)渲染。需要對返回的數(shù)據(jù)做去重處理,否則顯示在顏色和尺寸分類下的部分數(shù)據(jù)會存在數(shù)據(jù)重疊的情況,這顯然是不合理的。 比如,variants的第10到第12條數(shù)據(jù),測試這個顏色就重復了兩次。variants的第4、6、11條數(shù)據(jù),通用-42這個尺碼就重復了兩次。

<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> 
復制代碼
//監(jiān)聽傳入的product數(shù)據(jù),如果詳情接口請求成功,且能夠拿到詳情數(shù)據(jù),則使用集合過濾重復的顏色分類屬性
  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:顯示已選產(chǎn)品的屬性

??這個小需求其實由三部分組成,都是在點擊時觸發(fā):

??1. 顯示已選產(chǎn)品的分類屬性(點擊時觸發(fā)):

??如果沒有選擇產(chǎn)品的分類屬性,提示語為請選擇產(chǎn)品屬性;如果選擇了產(chǎn)品的分類屬性,則將選擇的產(chǎn)品分類屬性在產(chǎn)品sku組件中顯示出來。

??????????


?????????

??解決思路:

??既然是分不同條件顯示已選產(chǎn)品的分類屬性,最容易想到的自然是MINA框架里面的wx:ifwx:else。于是可以設定判斷條件,只要兩個分類屬性都沒有被選中,就提示請選擇產(chǎn)品屬性,否則顯示已選產(chǎn)品的分類屬性。那么如何獲取按鈕里面的值呢?其實只需要在產(chǎn)品分類屬性的點擊事件中,通過自定義屬性傳入當前點擊的對象,再獲取里面的值顯示到產(chǎn)品sku上就可以了。

<view class="message">
    <text wx:if="{{ selectedColor === '' && selectedSize === ''}}">請選擇產(chǎn)品屬性</text>
    <text wx:else>已選屬性: {{selectedColor}} {{selectedSize}}</text>
</view>
復制代碼

??2. 顯示已選產(chǎn)品的價格屬性(點擊時觸發(fā)):

??如果沒有選擇產(chǎn)品的分類屬性或者選擇的分類屬性只有顏色屬性或者尺碼屬性,顯示的產(chǎn)品價格為返回的產(chǎn)品詳情接口中的lowest_price字段;如果選中的分類屬性包含了顏色屬性和尺碼屬性,則會在返回的產(chǎn)品詳情接口中的variants對象數(shù)組中去查找對應分類屬性。如果能夠找到對應分類屬性的價格,則返回相應的價格,否則會報價格字段不存在的錯誤。因此需要做點擊分類屬性的屬性關聯(lián),這個會在需求3中解決。

??解決思路:

??邏輯是這樣的:監(jiān)聽傳入的product數(shù)據(jù),只要接收到了這個數(shù)據(jù)或者彈出層被關閉的時候,就立刻初始化currentPrice 的值,并將product.lowest_price的值賦給currentPrice 。在產(chǎn)品分類屬性的點擊事件中,判斷產(chǎn)品顏色分類屬性和尺寸分類屬性是否都有被選中。如果沒有,則顯示返回的產(chǎn)品詳情接口中的lowest_price字段;如果都有被選中,則在variants中去查找選中分類屬性對應的價格,如果找不到就會報價格字段不存在的錯誤。因此需要做點擊分類屬性的屬性關聯(lián),這個會在需求3中解決。

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

??3. 切換不同分類屬性的邏輯(點擊時觸發(fā)):

??拿點擊顏色分類屬性舉栗子。點擊顏色分類屬性之前,其實可以分為三種情況(最后有兩種情況結(jié)果一樣,可以歸并為一類):

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

??????????

  • 有顏色分類屬性被選中且選中的顏色分類屬性和要點擊的顏色分類屬性一致,此時點擊會取消激活的顏色分類屬性樣式;

??????????

  • 有顏色分類屬性被選中且選中的顏色分類屬性和要點擊的顏色分類屬性不一致,此時點擊會取消之前激活的顏色分類屬性樣式,并激活當前選中顏色分類屬性的樣式。

??????????

??解決思路: 舉選擇顏色分類屬性的栗子來說,可以使用一個變量判斷當前顏色分類屬性是否被選中,以及當前選中的顏色分類屬性對應的id。這樣就可以和當前點擊的對象的id做比較,從而處理不同的判斷邏輯。這也是為什么在需求1中重構詳情接口返回的數(shù)據(jù)時,除了取分類屬性名外,還要為它們分配id的原因。當然,在最后關閉彈出層的回調(diào)中,需要重置所選顏色分類屬性的文字和id、所選尺碼分類屬性的文字和id。

handleColorClicked(e) {
  //此處如果不使用if條件判斷,按鈕依然可以點擊
  if (!this.data.availableColorArray.includes(e.currentTarget.dataset.color.color)) return
  //比較當前選中對象的id和當前點擊對象的id
  //1.如果selectedSizeId === -1,則表明當前沒有顏色分類屬性被選中。此時點擊需要將當前點擊對象的id和值傳過去,傳id是為了進行下一次比較,傳值是為了顯示已選產(chǎn)品的分類屬性。
  //2.如果選中的顏色分類屬性id和當前點擊對象的id不一致。此時點擊除了會取消選中的顏色分類屬性,還會激活當前選中顏色分類的樣式(第一種情況和第二種情況是一樣的)。
  //3.如果選中顏色分類屬性的id和當前點擊對象的id一致。此時點擊會取消選中的顏色分類屬性,相當于清空選中的顏色分類屬性。
  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:處理點擊不同分類按鈕的屬性關聯(lián)問題

??點擊產(chǎn)品的顏色分類屬性,會篩選產(chǎn)品的尺碼分類屬性,可用的顯示,禁用的灰顯且不可點擊;取消選擇對應的顏色分類屬性后,產(chǎn)品的尺碼分類屬性會全部恢復為可用狀態(tài)。點擊產(chǎn)品的尺寸分類屬性也是同樣一個道理,所以需要為點擊不同的分類按鈕做屬性關聯(lián)。

??解決思路:

??以點擊顏色分類屬性舉例,聊一聊產(chǎn)品尺碼分類屬性的篩選原則。點擊顏色分類屬性后, 需要在產(chǎn)品的variants數(shù)據(jù)中,找到包含當前顏色分類屬性的variantsize。這一個或多個size就是點擊顏色分類屬性后當前可用的size屬性集,取反就是禁用的size屬性集。因為在需求2中已經(jīng)粘貼了點擊事件的代碼邏輯,此處就不再粘貼。

??這里有兩處地方需要特別注意:1.使用van-button循環(huán)遍歷分類數(shù)據(jù)后,disabled屬性的禁用原則是先篩選出可用的屬性集然后取反。如果先對當前點擊的color屬性取反,再通過可用的color屬性集選取禁用的size屬性集,可能會造成禁用的size屬性集中包含當前點擊的color屬性對應的可用的size屬性集;2.由于微信小程序不支持在函數(shù)中傳參,因此在禁用條件中需要使用wxs語言來判斷,不能使用!availableColorArray.includes(item.color)判斷。

// wxs不支持es6語法
//使用兩個逗號的原因是在于可能會有名字包含測試和測試色(一個顏色包含另外一個顏色的名稱)這類情況
//可以對數(shù)組循環(huán)遍歷,判斷名字是否一樣,如果一樣,就返回true
function hasTag(tags, name) {
  var testStr = ',' + tags.join(',') + ',' 
  return testStr.indexOf(',' + name + ',') != -1
}

// 導出
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:

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

// 導出
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 === ''}}">請選擇產(chǎn)品屬性</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">
        數(shù)量
    </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({
  /**
   * 組件的屬性列表
   */
  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
    }
  },
  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    value: 1,
    selectedColor: '',
    selectedSize: '',
    currentPrice: 100,
    colors: {},
    sizes: {},
    selectedColorId: -1,
    selectedSizeId: -1,
    availableSizeArray: [],
    availableColorArray: []
  },
  /**
   * 組件的方法列表
   */
  methods: {
    handleConfirmed() {
      this.setData({
        value: 1
      })     
      if(this.data.selectedColor !== '' && this.data.selectedSize !== '') {
        //全部選中且校驗成功時調(diào)用
        this.onClose()
        wx.showToast({
          title: '加入購物車成功',
          icon: 'success',
          duration: 2000
        })
      } else {
        //未全部選中時調(diào)用
        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) {
      //此處如果不使用if條件判斷,按鈕依然可以點擊
      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()
    },
    //禁用存在一對多的問題,不能直接使用該禁用的,只能使用未禁用的,然后再對未禁用的進行取反
    handleColorClicked(e) {
      //此處如果不使用if條件判斷,按鈕依然可以點擊
      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": {}
}
復制代碼


寫在最后

??由于代碼寫得比較倉促,本文的代碼邏輯還是比較復雜,而且存在大量的重復代碼,有時間和興趣的小伙伴可以使用組件化的思想重新編寫代碼。年少輕狂,總以為天下事,無可不為,歲月蹉跎,終感到天下人力有盡頭。年輕無知,總認為目光內(nèi),皆為好人,時間流轉(zhuǎn),終嘆息社會人笑里藏刀。社會很大,人心很復雜,一路走來,背最黑的鐵鍋,鬧最大的笑話。塞翁失馬,焉知非福,惋惜之余也慶幸自己遇到了這么好的媽,希望自己能保持本心,不被社會改變。

相關案例查看更多