Taro的关联选择器封装思路

325 阅读2分钟

Taro或微信小程序本身不提供可关联的选择器,前端🥬🐕遇到了需要关联的二级选择器的需求,防止他下次再问,把原理记录下来

1653890341(1).jpg

将定义的数据结构设计为二维数组

由于数据结构,一级级之间是有关联的,定义为类似以下的二维数组的数据是比较合理的,也是比较方便处理的

let data = [{
    key: 2,
    value: '三方',
    children: [{
        key: 1,
        value: '全部'
    }, {
        key: 2,
        value: '滴滴'
    }]
}]

state数据

state中的数据,至少要有3个

  1. 确定后的index,分别是以及和二级的index
  2. 当前滚动到的index
  3. 选择器需要传入的数据
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>
    )
}

以上就是二级的关联选择器的封装,如果需要更多级的关联,原理也是相同,只是需要做更多的数据处理