1. 程式人生 > >微信小程式中遇到的多規格問題(一)

微信小程式中遇到的多規格問題(一)

剛進入公司的時候就有遇到過多規格的問題,當時就覺得很麻煩,就只是看了下,沒有嘗試,最近在寫微信小程式的時候,又遇到了多規格問題,就自己嘗試了下,在這裡記錄下

1.效果圖

2.檔案及部分思路

  • index.wxml檔案
<view class="multipleStandard" bindtap="standardSelect">
  <view class="standard">
    規格:
    <text class="item">顏色</text>    
    <text class="item">顏色</text>    
    <text class="item">顏色</text>    
  </view>
  <image src="/images/arrows.png" class="arrows"></image>
</view>
<view style="background:rgb(207, 224, 232); height: 300rpx;margin-top: 50rpx;"></view>
<view animation="{{animationData}}" class="selectStandard" catchtouchmove="noMove">
  <view class="tophead">
    <view class="topimg">
      <image src="{{goods.original_img}}"></image>
    </view>
    <view class="topright">
      <view class="selectClose">
        <view style="color:#ef5426;">{{standardObject.price}}</view>
        <image src="/images/close.png" bindtap="handleClose"></image>
      </view>
      <view style="margin:10rpx 0;color:#999999;">庫存:{{standardObject.store_count}}</view>
      <view>規格: {{mergeStandard}}</view>
    </view>
  </view>
  <view class="standard" wx:for="{{commodityStandard}}" wx:key="{{standardIndex}}" wx:for-index="standardIndex">
    <view class="standardTitle">{{item[0].spec_name}}</view>
    <view class="standardItem">
      <block wx:for="{{item}}" wx:key="{{item.item_id}}">
        <view class="selectItem {{isSelect[item.isClick]}}" bindtap="handleStandardClick" data-standard-index="{{standardIndex}}" data-index="{{index}}" data-id="{{item.item_id}}">{{item.item}}</view>        
      </block>
    </view>
    <view style="height:1px; width:100%;background-color:#eeeeee;"></view>
  </view>
  <view class="selectCount">
    <view class="countname">數量</view>
    <view class="countright">
      <i-input-number value="{{commodityNum}}" min="1" max="{{store_count}}" bindchange="handleCommodityNumber" />
    </view>
  </view>
  <view class="submitBtn" bindtap="submitSelected">
    確定
  </view>
</view>
<i-message id="message" />
  • index.wxss檔案
.multipleStandard{
  display: flex;
  margin-top: 20rpx;
  padding: 15rpx 20rpx;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 0 10px #ccc;
}
.item{
  margin-right: 15rpx;
}
.arrows{
  width: 16rpx;
  height: 27rpx;
}

/* 規格彈窗 */
.selectStandard {
  width: 100%;
  height: 1000rpx;
  background-color: #fff;
  position: fixed;
  z-index: 333;
  bottom: -600px;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
}

/* 頭部選中的規格 */
.tophead {
  display: flex;
  margin: 30rpx 3%;
  width: 94%;
  align-items: center;
  text-align: center;
}

.topimg {
  width: 200rpx;
  height: 200rpx;
}

.topimg image {
  width: 100%;
  height: 100%;
  border-radius: 20rpx;
  background-color: red;
}

.topright {
  margin-left: 30rpx;
  font-size: 28rpx;
  text-align: left;
  width: 66%;
}
/* 關閉按鈕 */
.selectClose {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.selectClose image {
  width: 30rpx;
  height: 30rpx;
}

.standard {
  margin: 0 3%;
  width: 94%;
  font-size: 28rpx;
}

.standardTitle {
  font-size: 30rpx;
  margin-top: 20rpx;
}
.standardItem {
  display: flex;
  flex-wrap: wrap;
    width: 100%;
}
.selectItem {
  border: solid 1px #666;
  margin: 20rpx;
  padding: 5rpx 23rpx;
  border-radius: 16rpx;
}
/* 規格選中時樣式 */
.standardSelected{
  color: #fff;
  background: #f26740;
    background-color:#fe6732;
    border:solid 1px #fe6732;
    margin:20rpx;
    padding:5rpx 23rpx;
    border-radius:16rpx;
}
.standardNormal{
  color: #000;
}
.standardDisable{
  color: #eee;
}

/* 選擇的數量 */
.selectCount {
  margin: 30rpx 3%;
  width: 94%;
  font-size: 28rpx;
}
.countright {
  float: right;
  display: flex;
  text-align: center;
  align-items: center;
}

.countname {
  margin-bottom: 20rpx;
  font-size: 30rpx;
}

.submitBtn {
  position: absolute;
  bottom: 0;
  width: 70%;
  margin: 0 15% 20rpx 15%;
  text-align: center;
  z-index: 66;
  height: 80rpx;
  background-color: #fe6732;
  border-radius: 40rpx;
  color: white;
  font-size: 32rpx;
  line-height: 80rpx;
}
  • index.js檔案
const {
    $Message
} = require('../../component/iview/base/index');
Page({
  data: {
    animationData: {},
    isSelect: ["standardNormal", "standardSelected", "standardDisable"],  /* 用於區別當前的規格是否選中 */
    goods: {
      goods_name: "男鞋",
      store_count: 158,
      cost_price: "10.00",
      original_img: "/images/commodity.jpg",     
    },
    commodityStandard: [
      [
        {
          spec_name: "顏色",
          item_id: 535385,
          item: "白色",
          src: "",
          isClick: 0
        },
        {
          spec_name: "顏色",
          item_id: 535386,
          item: "黑色",
          src: "",
          isClick: 0
        }
      ],
      [
        {
          spec_name: "尺寸",
          item_id: 535692,
          item: "170",
          src: "",
          isClick: 0
        },
        {
          spec_name: "尺寸",
          item_id: 535693,
          item: "180",
          src: "",
          isClick: 0
        }
      ],
      [
        {
          spec_name: "重量",
          item_id: 552569,
          item: "11",
          src: "",
          isClick: 0
        },
        {
          spec_name: "重量",
          item_id: 552570,
          item: "15",
          src: "",
          isClick: 0
        }
      ]
    ],
    standardInfo: [
      {
        id: 1018269,
        key: "535385_535692_552569",
        price: "10.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018270,
        key: "535385_535692_552570",
        price: "20.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018271,
        key: "535385_535693_552569",
        price: "30.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018272,
        key: "535385_535693_552570",
        price: "40.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018273,
        key: "535386_535692_552569",
        price: "50.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018274,
        key: "535386_535692_552570",
        price: "60.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018275,
        key: "535386_535693_552569",
        price: "70.00",
        productprice: "0.00",
        store_count: 20
      },
      {
        id: 1018276,
        key: "535386_535693_552570",
        price: "80.00",
        productprice: "0.00",
        store_count: 18
      }
    ],
    selectedId: [],
    selectedStandard: [],
    standardObject: {},
    commodityNum: 1,
  },
  onLoad: function (options) {
    let goods = this.data.goods;
    let standardObject = this.data.standardObject;
    standardObject.price = goods.cost_price;
    standardObject.store_count = goods.store_count;
        let store_count = goods.store_count;
    this.setData({
      standardObject,
            store_count
    })
  },
  /* 規格選擇 */
  standardSelect() {
    var that = this
    var animal1 = wx.createAnimation({
      timingFunction: 'ease-in'
    }).translate(0, -600).step({
      duration: 300
    })
    that.setData({
      animationData: animal1.export(),
    })
  },
  /* 關閉規格選擇 */
  handleClose() {
    var that = this
    var animal1 = wx.createAnimation({
      timingFunction: 'ease-in'
    }).translate(0, 600).step({
      duration: 300
    })
    that.setData({
      animationData: animal1.export()
    })
  },
  /* 每個規格的點選事件 */
  handleStandardClick(e) {
    let id = e.currentTarget.dataset.id;
    // 總規格名稱索引
    let standardIndex = e.currentTarget.dataset.standardIndex;
    // 單個規格名稱索引
    let index = e.currentTarget.dataset.index;
    let commodityStandard = this.data.commodityStandard;
    let standardLength = commodityStandard[standardIndex].length;

    // 用於儲存規格的id
    let selectedId = this.data.selectedId;
    // 用總規格名稱索引來儲存每個選中的規格id
    selectedId[standardIndex] = id;

    let selectedStandard = this.data.selectedStandard;

    // 在點選的時候,只需要對點選的這個規格所在的陣列進行迴圈
    for (let i = 0; i < standardLength; i++) {
      // 找到對應的單個規格索引,並設定isClick及單個規格名稱
      if (index == i) {
        commodityStandard[standardIndex][index].isClick = 1;
        selectedStandard[standardIndex] = commodityStandard[standardIndex][index].item;
      } else {
        commodityStandard[standardIndex][i].isClick = 0;
      }
    }

    // 將id用_連線起來
    let mergeId = selectedId.join('_');
    console.log(mergeId);
    let mergeStandard = selectedStandard.join('  ');
    console.log(mergeStandard);

    let standardInfo = this.data.standardInfo;
    let standardInfoLength = standardInfo.length;
    // 用於儲存選中的規格
    let standardObject = {};

    for (let i = 0; i < standardInfoLength; i++) {
      if (standardInfo[i].key == mergeId) {
        standardObject = standardInfo[i];
        break;
      } else {
        standardObject = this.data.standardObject;
      }
    }

    this.setData({
      currentId: id,
      commodityStandard,
      selectedId,
      standardObject,
      mergeStandard,
      selectedStandard,
    })

  },
  /* 選擇數量 */
  handleCommodityNumber(e) {
      let commodityNum = e.detail.value;
      if (commodityNum >= this.data.store_count) {
          commodityNum = this.data.store_count;
      }
      this.setData({
          commodityNum
      })
  },
  /* 儲存選擇的規格 */
  submitSelected() {
      let selectedStandard = this.data.selectedStandard;
      let length = selectedStandard.length;
      console.log(length)
      if (length == 0) {
          $Message({
              content: '請選擇規格',
              type: 'error'
          });
          return false;
      }
      for (let i = 0; i < length; i++) {
          if (length < this.data.commodityStandard.length) {
              $Message({
                  content: '請選擇規格',
                  type: 'error'
              });
              break;
          }
          if (selectedStandard[i] == undefined) {
              $Message({
                  content: '請選擇規格',
                  type: 'error'
              });
              break;
          }
      }
      $Message({
          content: '選擇成功',
          type: 'success'
      });
  },
})
  • 我這裡提示資訊使用了外掛iview,可以在官網直接下載後使用
iview weapp

3.部分思路及改進方法

開始想到的是將需合併的id的位置寫死,比如,第一個位置就傳第一個規格里選中的規格id,第二個位置就傳第二個規格里選中的規格id,不過此時有問題,就是後臺的id拼接是根據當前規格長度來拼接的,從最短的開始往長的拼接,然後,長度相等的時候,我這邊的話,後臺是從第一個開始拼接的,而且你選規格時,也可能是隨機點的,此時若是採用第一種位置寫死的方法就會有問題,因為會找不到對應的合併後的規格id
  • 因為我這裡一開始用的資料就剛好滿足我的設想,但是後面換了個數據後就出現問題了
  • index.wxml檔案也做部分修改,可以直接查詢下,類名為standardItem
<view class="standardItem">
  <block wx:for="{{item}}" wx:key="{{item.item_id}}">
    <view class="selectItem {{item.item_id == Specifications[standardIndex]?'standardSelected':'standardNormal'}}" bindtap="handleStandardClick" data-standard-index="{{standardIndex}}" data-name="{{item.item}}" data-id="{{item.item_id}}">{{item.item}}</view>        
  </block>
</view>

*增加另一種模擬資料

goods: {
  goods_name: "男鞋",
  store_count: 95,
  market_price: "10.00",
  shop_price: "101.00",
  cost_price: "10.00",
  original_img: "/images/commodity.jpg",
  store_id: 170,
},
commodityStandard: [
  [
    {
      spec_name: "顏色",
      item_id: 532825,
      item: "白色",
      src: "",
      isClick: 0
    },
    {
      spec_name: "顏色",
      item_id: 532826,
      item: "黑色",
      src: "",
      isClick: 0
    },
    {
      spec_name: "顏色",
      item_id: 532827,
      item: "紅色",
      src: "",
      isClick: 0
    }
  ],
  [
    {
      spec_name: "大小",
      item_id: 532828,
      item: "160",
      src: "",
      isClick: 0
    },
    {
      spec_name: "大小",
      item_id: 532829,
      item: "150",
      src: "",
      isClick: 0
    }
  ],
  [
    {
      spec_name: "重量",
      item_id: 552581,
      item: "10",
      src: "",
      isClick: 0
    }
  ]
],
/* 這裡合併規格的資訊 */
spec_goods_price: [
  {
    id: 1018286,
    key: "552581_532828_532825",
    price: "10.00",
    productprice: "0.00",
    store_count: 9
  },
  {
    id: 1018287,
    key: "552581_532828_532826",
    price: "20.00",
    productprice: "0.00",
    store_count: 10
  },
  {
    id: 1018288,
    key: "552581_532828_532827",
    price: "30.00",
    productprice: "0.00",
    store_count: 10
  },
  {
    id: 1018289,
    key: "552581_532829_532825",
    price: "40.00",
    productprice: "0.00",
    store_count: 10
  },
  {
    id: 1018290,
    key: "552581_532829_532826",
    price: "50.00",
    productprice: "0.00",
    store_count: 7
  },
  {
    id: 1018291,
    key: "552581_532829_532827",
    price: "60.00",
    productprice: "0.00",
    store_count: 10
  }
],
  • index.js檔案
onLoad: function (options) {
    let goods = this.data.goods;
    /* 用於儲存對應的價格及庫存 */
    let standardObject = this.data.standardObject;
    standardObject.price = goods.cost_price;
    standardObject.store_count = goods.store_count;
    
    let spec_goods_price =this.data.spec_goods_price;
    if (spec_goods_price) {
      this.checkPrice(spec_goods_price);
    }
    this.setData({
      standardObject,
    })
},
handleStandardClick: function (e) {
    // 總規格名稱索引
    let standardIndex = e.currentTarget.dataset.standardIndex;
    let id = e.currentTarget.dataset.id;
    /* 儲存選中的規格名稱 */
    let name = e.currentTarget.dataset.name;
    let selectedStandard = this.data.selectedStandard;
    selectedStandard[standardIndex] = name;
    let mergeStandard = selectedStandard.join('  ');
    let Specifications = this.data.Specifications;
    Specifications[standardIndex] = id;
    console.log(mergeStandard)
    this.setData({
      Specifications,
      mergeStandard,
      selectedStandard,
    })
    this.checkPrice(this.data.spec_goods_price);
},
/*在還未選擇完規格時,暫時選用第一個合併後的規格價格及庫存*/
checkPrice: function (spec_goods_price) {
    let standardObject = this.data.standardObject;
    if (!this.checkSpecifications(spec_goods_price)) {
      standardObject.price = spec_goods_price[0].price;
      standardObject.store_count = spec_goods_price[0].store_count;
      this.setData({
        standardObject,
      })
    }
},
/* 儲存及校驗是否選好了規格 */
submitSelected: function (e) {
    let spec_goods_price = this.data.spec_goods_price;
    let i = 0;
    let optionid = "";
    if (spec_goods_price) {
        optionid = this.checkSpecifications();
        if (optionid) {
            $Message({
              content: '選擇成功',
              type: 'success'
            });
        } else {
            $Message({
              content: '請選擇規格',
              type: 'error'
            });
        }
    }
},
checkSpecifications(spec_goods) {
    let spec_goods_price = spec_goods || this.data.spec_goods_price;
    let Specifications = this.data.Specifications;
    let SpecificationsLength = spec_goods_price[0].key.split("_").length;
    let standardObject = this.data.standardObject;
    if (Specifications.length != SpecificationsLength) {
      return false;
    } else {
      for (let i = 0; i < spec_goods_price.length; i++) {
        /* 若selectSpecifications全為true,則選中了對應的合併後的規格 */
        let selectSpecifications = true;
        for (let j = 0; j < Specifications.length; j++) {
          if (spec_goods_price[i].key.indexOf(Specifications[j]) == -1) {
            selectSpecifications = false;
            break;
          }
        }
        if (selectSpecifications) {
          standardObject.price = spec_goods_price[i].price;
          standardObject.store_count = spec_goods_price[i].store_count;
          this.setData({
            standardObject,
          })
          return spec_goods_price[i].id;
        }
      }
    }
    return false;
},
  • 利用indexOf來判斷合併後的key值,就不用通過寫死位置儲存規格,然後這裡用了動畫,可以自己檢視官方完檔微信建立動畫