首先看看全文要實作的效果圖:
說明:在“釋出我的閑置物品”這個頁面裡,有一個所屬分類的選項,我選擇使用小程式原生的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 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 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
}
}