# Cube-Cascade-Picker
# 介绍
CascadePicker 组件是级联选择器,用于实现多列选择之间的级联变化。比如,在选择省市区时,当省切换到了江苏省,城市列应该变成江苏省的各个城市,同理,如果城市切换到苏州市,区列的选项也应变成苏州市的各个区,这就级联的意义。
# 示例
# 基础用法
相比普通选择器,级联选择器需要传入的数据结构是不一样的。普通选择器的数据结构是一个二维数组,每一列对应一个固定的数组,而级联选择器,则需要传入的是一个树形结构,第一列数组的每个选项的children属性,对应着切换到该选项时后续列的数据,从而实现对后续列的改变。
如 Picker 组件一样,当你需要获取 CascadePicker 当前选择项时,你可以使用实例方法 getSelectedInfo。
<template>
<view>
<view class="picker-demo-title">basic-cascade-picker:</view>
<cube-cascade-picker
wx:ref="picker"
list="{{dataList}}"
selectedIndex="{{selectedIndex}}"
bindcolumnChange="onColumnChange"
bindchange="onChange"
/>
<view class="button-wrapper">
<cube-button bindclick="getSelected">获取当前选中项</cube-button>
</view>
<view class="demo-data" wx:if="{{ selectedInfo.length || changeParams.length }}">
<block wx:if="{{ selectedInfo.length }}">
<view class="key">getSelectedInfo 事件返回值:</view>
<view class="value">
<view class="value-item" wx:for="{{selectedInfo}}" wx:key="index">
<view class="item-key">{{item[0]}}</view>
<view class="item-value">{{item[1]}}</view>
</view>
</view>
</block>
<block wx:if="{{ changeParams.length }}">
<view class="key">change 事件参数:</view>
<view class="value">
<view class="value-item" wx:for="{{changeParams}}" wx:key="index">
<view class="item-key">{{item[0]}}</view>
<view class="item-value">{{item[1]}}</view>
</view>
</view>
</block>
<block wx:if="{{ changeParams.length }}">
<view class="key">columnChange 事件参数:</view>
<view class="value">
<view wx:for="{{ columnChangeParams }}" wx:key="index">
<view class="value-number">第{{ index+1 }}次:</view>
<view class="value-item" wx:for="{{item}}" wx:for-item="itemChild" wx:for-index="itemIndex" wx:key="itemIndex">
<view class="item-key">{{itemChild[0]}}</view>
<view class="item-value">{{itemChild[1]}}</view>
</view>
</view>
</view>
</block>
</view>
</view>
</template>
<script>
import { createComponent } from '@mpxjs/core'
import { beauty } from '../../common/utils'
let columnChangeArr = []
createComponent({
data: {
selectedIndex: [0, 1, 0],
columnChangeParams: [],
changeParams: '',
selectedInfo: '',
dataList: [{
value: 'Fruit',
text: 'Fruit',
children: [{
value: 'Apple',
text: 'Apple',
children: [{ value: 1, text: 'One' }, { value: 2, text: 'Two' }]
}, {
value: 'Orange',
text: 'Orange',
children: [{ value: 3, text: 'Three'}, { value: 4, text: 'Four' }]
}]
}, {
value: 'Drink',
text: 'Drink',
children: [{
value: 'Coffee',
text: 'Coffee',
children: [{ value: 1, text: 'One' }, { value: 2, text: 'Two' }]
}, {
value: 'Tea',
text: 'Tea',
children: [{ value: 1, text: 'One' }, { value: 3, text: 'Three'}]
}]
}]
},
computed: {
isShowSelectedInfo() {
return !this.selectedInfo
},
isShowOther() {
return !this.columnChangeParams[0] && !this.changeParams
}
},
methods: {
onColumnChange(e) {
columnChangeArr.push(Object.entries(e.detail))
},
onChange(e) {
this.columnChangeParams = [...columnChangeArr]
columnChangeArr = []
this.changeParams = Object.entries(e.detail)
},
getSelected() {
this.selectedInfo = Object.entries(this.$refs.picker.getSelectedInfo())
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
当第一列选中Fruit
时,第二列的选项是Apple
、Orange
。以此类推,当第二列选中Orange
时,第三列的选项是Three
、Four
。
# 异步加载数据
当数据量太大时,可能难以在最开始就生成完整的级联数据树。这时,你可以配置 async 属性开启异步加载级联数据,在 columnChange 事件时去更新数据,并且在你更新完数据之前,用户点击确认会是无效的。
数据的更新可以使用实例方法 updateData,传入你需要更新的属性。同时因 async 属性,例子有以下表现:
- 分别有两组数据 Fruit 和 Drink,同时只有一组和子数据。
- 切换一级选项后,有对数据进行更新,所以在更新后 cascade-picker 派发 change 事件。
- 切换二级选项后,没有对数据进行更新,所以二级选项变化后 change 事件不会触发。
- 切换最后一级后,因不涉及到子数据的变化,所以会触发 change 事件。
<template>
<view>
<view class="picker-demo-title">async-cascade-picker:</view>
<cube-cascade-picker
wx:ref="asyncPicker"
list="{{dataList}}"
selectedIndex="{{selectedIndex}}"
async="{{true}}"
bindcolumnChange="onColumnChange"
bindchange="onChange"
/>
<view class="event-params m-t-10" wx:if="{{ changeParams || introduce }}">
<view class="key-introduce">{{introduce}}</view>
<view class="desc-text m-t-10 m-b-10">
因设置 async 为true,change 事件会在用户更新数据后才相应;例子里第二例滚动时没有更新数据,所以无 change 事件。
</view>
<block wx:if="{{ changeParams }}">
<view class="m-b-10">change 事件参数:</view>
<view class="value m-b-10">
<view view class="value-item" wx:for="{{changeParams}}" wx:key="index">
<view class="item-key">{{item[0]}}</view>
<view class="item-value">{{item[1]}}</view>
</view>
</view>
</block>
</view>
</view>
</template>
<script>
import { createComponent } from '@mpxjs/core'
import { beauty } from '../../common/utils'
const Fruit = [{
value: 'Fruit',
text: 'Fruit',
children: [{
value: 'Apple',
text: 'Apple',
children: [{ value: 1, text: 'One' }, { value: 2, text: 'Two' }]
}, {
value: 'Orange',
text: 'Orange',
children: [{ value: 3, text: 'Three'}, { value: 4, text: 'Four' }]
}]
}, {
value: 'Drink',
text: 'Drink'
}]
const Drink = [{
value: 'Fruit',
text: 'Fruit'
}, {
value: 'Drink',
text: 'Drink',
children: [{
value: 'Coffee',
text: 'Coffee',
children: [{ value: 1, text: 'One' }, { value: 2, text: 'Two' }]
}, {
value: 'Tea',
text: 'Tea',
children: [{ value: 1, text: 'One' }, { value: 3, text: 'Three'}]
}]
}]
createComponent({
data: {
dataList: Fruit,
selectedIndex: [0, 1, 1],
changeParams: '',
introduce: '',
load: false
},
computed: {
isShow() {
return !this.changeParams
},
isShowLoad() {
return this.load
}
},
methods: {
onColumnChange(e) {
this.changeParams = ''
this.introduce = 'change 事件未触发'
const { column, index, value } = e.detail
if (column === 0) {
this.introduce = '数据更新中...'
this.load = true
// 模拟1.5秒后返回数据
setTimeout(() => {
this.$refs.asyncPicker.updateData(index === 0 ? Fruit : Drink, [index, 0, 0])
this.load = false
}, 1500)
}
},
onChange(e) {
this.introduce = ''
this.changeParams = Object.entries(e.detail)
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Props
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
themeType | 用于生成最外层类名 如原类名为 cube-component,添加 themeType = demo 后,类名变为 cube-component cube-component-demo | String | - | - |
selectedIndex | 被选中的索引值,拉起 picker 后显示这个索引值对应的内容 | Array | - | number[] |
immediateChange | 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件。 微信 webview 特有属性,基础库 2.21.1 及以上; 支付宝需基础库 2.8.7 及以上 | Boolean | - | false |
list | 级联选择器的树形数据,用于初始化选项 | Array | - | CascadePickerSubTree[] |
async | 是否异步加载数据 | Boolean | - | false |
# TsType
Name | Type |
---|---|
PickerColumn |
|
CascadePickerSubTree |
|
# Events
事件名 | 说明 | 参数 |
---|---|---|
pickstart | 当滚动选择开始时候触发事件 | - |
pickend | 当滚动选择结束时候触发事件 | - |
pendingChange | async 为 true 时使用,组件等待数据及数据更新时触发 | e.detail = { pending },pending 为 true/false。更新时为 false,等待时为 true |
change | 滚动后触发 | event.detail = { selectedIndex, selectedText, selectedVal } 每个属性都是数组,是当前所有列的选中信息; 分别表示被选中的索引、文案、值 |
columnChange | 列变化事件,某列选中的 value 及 index 任意一个变化后触发事件 | event.detail = { column, index, text, value } column 是发生变化的列;index, text, value 分别是变化后的索引、文案、值 |
# Methods
组件实例方法 | 说明 | 参数 1 | 参数 2 | 返回值 |
---|---|---|---|---|
updateData | 更新 picker 的数据及选中值 | list 为每一列的数据 | index 为每一列的数据选中的索引 | - |
updateList | 更新 picker 的数据 | list 为每一列的数据 | - | - |
updateIndex | 更新 picker 的选中值 | index 为每一列的数据选中的索引 | - | - |
getSelectedInfo | 获取当前所有列的选中信息 | - | - | { selectedIndex, selectedText, selectedVal } 每个属性都是数组,是当前所有列的选中信息; 分别表示被选中的索引、文案、值。 |