mpvue:用picker實現普通滾動選擇組件並向父組件返回選中的值

首先看看全文要實現的效果圖:

說明:在“發佈我的閒置物品”這個頁面裏,有一個所屬分類的選項,我選擇使用小程序原生的picker來做普通的滾動選擇。這裏,實現“發佈我的閒置物品”這個頁面的/src/pages/createGoods/index.vue作爲父組件,另外封裝/src/components/selectBox.vue作爲子組件來實現滾動選擇器。父組件將需要渲染的可選值(例如:電子產品、運動器材等)通過props傳遞給子組件。然後子組件將被選中的值通過$emit返回給父組件。

在父組件中,首先獲取所有分類,得到數據形式如下:

爲了 不分散注意,以下展示的代碼只貼出分類目錄相關部分,父組件/src/pages/createGoods/index.vue代碼如下:

<template>
  <div class="wrapper">
    <div class="properties">
      <div>
        <span class="mark"> * </span>
        <label class="title">所屬分類:</label>
        <selectBox @selectedValue="updateBelongsCategory" :selectList="categoryList" ></selectBox>
      </div>
    </div>
  </div>
</template>

<script>
import selectBox from '@/components/selectBox'
export default {
  data () {
    return {
      categoryList: [],
      belongsCategory: 0
    }
  },
  components: {
    selectBox
  },
  methods: {
    //  接收子組件傳值,獲取選中的分類ID
    updateBelongsCategory (val) {
      this.belongsCategory = val
    },
    //  獲取所有分類
    async initCategoryData () {
      await this.$http.get({
        'url': '/category/all'
      }).then(res => {
        //    使用nextTick同步視圖更新
        this.$nextTick(() => {
          //    爲了讓子組件更加通用,這裏將category_id更換爲code,在子組件中將通過code來獲取分類id
          let arr = JSON.parse(JSON.stringify(res).replace(/category_id/g, 'code'))
          this.categoryList = arr
        })
      })
    }
  },
  onLoad () {
    this.initCategoryData()
  }
}
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
.wrapper
  .properties
    font-size: 34rpx
    &>div
      padding: 20rpx 0
      display: flex
      line-height: 150%
      &>input
        width: 100%
        border: 1rpx solid #f4f4f4
        text-align: center
        padding: 10rpx 0
    .mark
      color: red;
      margin-right: 10rpx;
    .title
      white-space: nowrap
</style>

在父組件中傳遞給子組件的數據是object array類型的,我們在滾動選擇器中要顯示的名稱就是該對象數組中每個對象的name屬性,選中後我們應該將被選中對象的code屬性值回傳給父組件。根據微信開放文檔,可以使用mode=selector,range來表示選擇器的數據域,當range是個object array類型的時候,可以通過range-key來指定object中key的值作爲顯示內容。子組件/src/components/selectBox.vue代碼如下:

<template>
  <div class="select_box">
    <picker mode="selector" :value="selectList[index].code" :range="selectList" range-key='name' @change="pickerChange">
      <view class="picker">
        {{selectList[index].name}}
      </view>
    </picker>
  </div>
</template>

<script>
export default {
  props: {
    'selectList': {
      type: Array
    }
  },
  data () {
    return {
      index: 0//  數組下角標
    }
  },
  methods: {
    //  改變選項
    pickerChange (e) {
      let value = e.mp.detail.value
      this.index = value
      //  發佈自定義事件向父組件使傳遞數據
      this.$emit('selectedValue', this.selectList[value].code)
    }
  }
}
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
.select_box
  width: 100%
  text-align: center
  border: 1rpx solid #f4f4f4
</style>

對上述代碼作說明:

在子組件/src/components/selectBox.vue中,接收父組件傳遞過來的對象數組類型數據:selectList,在picker標籤中通過range指定selectList的值提供用戶選擇,range-key指定selectList數組中每個對象的name屬性值作爲顯示內容。用index記錄被選中對象在數組中的下角標,index初始值爲0。value值爲被選中對象的code屬性值

    <picker mode="selector" :value="selectList[index].code" :range="selectList" range-key='name' @change="pickerChange">
      <view class="picker">
        {{selectList[index].name}}
      </view>
    </picker>

當value值發生變化時,會觸發change事件。也就是用戶選擇完畢時會觸發change綁定的事件pickerChange()。在pickerChange()方法中,e.mp.detail.value代表當前被選中對象在數組中的下角標。通過下角標可以獲取當前被選中對象的code屬性值。再通過$emit(event,arg)方法,綁定自定義event事件:selectedValue事件,並將code值作爲參數傳遞給父組件。

methods: {
    //  改變選項
    pickerChange (e) {
      let value = e.mp.detail.value
      this.index = value
      //  發佈自定義事件向父組件使傳遞數據
      this.$emit('selectedValue', this.selectList[value].code)
    }
  }

父組件通過在使用子組件時,@event(即@selectedValue="父組件方法")即可獲取到子組件傳遞過來的值。

//    父組件中使用子組件時,監聽了自定義事件:selectedValue事件
<selectBox @selectedValue="updateBelongsCategory" :selectList="categoryList" ></selectBox>


//    父組件方法updateBelongsCategory
methods: {
    //  接收子組件傳值,獲取選中的分類ID
    updateBelongsCategory (val) {
      this.belongsCategory = val
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章