Taro或微信小程序本身不提供可关联的选择器,前端🥬🐕遇到了需要关联的二级选择器的需求,防止他下次再问,把原理记录下来
将定义的数据结构设计为二维数组
由于数据结构,一级级之间是有关联的,定义为类似以下的二维数组的数据是比较合理的,也是比较方便处理的
let data = [{
key: 2,
value: '三方',
children: [{
key: 1,
value: '全部'
}, {
key: 2,
value: '滴滴'
}]
}]
state数据
state中的数据,至少要有3个
- 确定后的index,分别是以及和二级的index
- 当前滚动到的index
- 选择器需要传入的数据
this.state = {
selectedIndex: [0, 0],//确定后的
currentIndex: [0, 0],
selector: [],
}
用一个方法处理菜单数据
由于UI组件需要以下数据结构,将定义的二维数组数据处理成以下数据结构并传入ui组件中
selector: [
[
{ key: 1, value: '全部' },
{ key: 2, value: '第三方' },
{ key: 3, value: '自营' }
], [
{ key: 1, value: '全部' },
{ key: 2, value: '滴滴' },
{ key: 3, value: '百度' }
]
],
由于第一级的index改变的时候,选择器需要传入的数据也会跟着改变,所以封装成根据index去改变selector数据,在初始化和第一级index改变时调用此方法
handleSelector = () => {
let { selector, currentIndex } = this.state;
let index = currentIndex[0];
selector[0] = data.map(item => { return { key: item.key, value: item.value } });
selector[1] = data[index].children;
this.setState({
selector,
})
}
改变第一级index时,重新加载菜单数据
onColumnChange = e => {
if (e.detail.column === 0) {
this.setState({
currentIndex: [e.detail.value, 0]
}, this.handleSelector)
}
}
双向绑定value
onChange = e => {
this.setState({
selectedIndex: e.detail.value
});
}
取消时,把当前value变为已选value
onCancel = () => {
let { selectedIndex } = this.state;
this.setState({
currentIndex: selectedIndex
}, this.handleSelector)
}
render结构
假如不熟悉jsx写法或原理,可以先将第三行的selectedTitle当作是vue里面的computed
render() {
let { selectedIndex, selector, currentIndex } = this.state;
let selectedTitle = data[selectedIndex[0]].value + '-' + data[selectedIndex[0]].children[selectedIndex[1]].value;
return (
<Picker
mode='multiSelector'
range={selector}
rangeKey={'value'}
value={currentIndex}
onChange={this.onChange}
onColumnChange={this.onColumnChange}
onCancel={this.onCancel}>
<View>
当前选择:{selectedTitle}
</View>
<View>
当前下标:{selectedIndex.join('-')}
</View>
</Picker>
)
}
以上就是二级的关联选择器的封装,如果需要更多级的关联,原理也是相同,只是需要做更多的数据处理