|
2 | 2 |
|
3 | 3 | ### 简介 |
4 | 4 |
|
5 | | -- 微信小程序的Picker组件只是**半成品**组件,在启用多级联动时需要监听`bindcolumnchange`事件,来手动更改`range`和`value`的值,从而完成Picker的联动变化,比较麻烦,不利于在不同的业务逻辑中的复用。 |
| 5 | +- 微信小程序的Picker组件只是半成品组件,在启用多级联动时需要监听`bindcolumnchange`事件,来手动更改`range`和`value`的值,从而完成Picker的联动变化,比较麻烦,不利于在不同的业务逻辑中的复用。 |
6 | 6 | - 本组件为了解决以上痛点,对微信小程序原生Picker组件进行了二次封装。开发者只需要提供固定数据结构的`sourceData`,再进行一些必要配置,本组件就可以自动帮助开发者处理联动逻辑。 |
| 7 | +- 本组件支持npm构建,从小程序基础库版本`2.2.1`或以上、及`开发者工具1.02.1808300`或以上开始,小程序支持使用 npm 安装第三方包。 |
7 | 8 |
|
8 | 9 | ## API |
9 | 10 |
|
|
34 | 35 |
|
35 | 36 | ### 规则 |
36 | 37 |
|
37 | | -- `sourceData`为源数组,是一个数组对象结构的集合,`sourceData`有几维,Picker就可以有几阶。 |
38 | | -- `steps`,你需要明确指定Picker的阶数,比如三级联动则设置`steps: 3`。 |
39 | | -- 需要注意的是,比如`steps`设置了`3`,那么`sourceData`务必要满足这个阶数。 |
40 | | -- `initColumnSelectedIndex`属性启用后,开发者调试工具上会有失效情况,但是真机目前没有发现问题,所以是否开启请开发者自行决定。 |
41 | | -- `bindchange`触发的事件对象: |
42 | | - - `selectedIndex`:Picker选择项的索引数组; |
43 | | - - `selectedArray`:Picker选择项的值数组; |
44 | | -- 本组件的有些方法和属性与微信原生API的行为完全一致,比如:`bindchange`,`bindcancel`,`bindcolumnchange`,`disabled`。 |
45 | | - |
46 | | -## 示例 |
47 | | - |
48 | | -```json |
49 | | -{ |
50 | | - "usingComponents": { |
51 | | - "comp": "../../components/index" |
52 | | - } |
53 | | -} |
54 | | -``` |
55 | | - |
56 | | -```xml |
57 | | -<comp |
58 | | - sourceData="{{sourceData_1}}" |
59 | | - steps="{{3}}" |
60 | | - shownFieldName="{{'name'}}" |
61 | | - subsetFieldName="{{'sonValue'}}" |
62 | | - otherNeedFieldsName="{{['id', 'other']}}" |
63 | | - defaultValue="{{[{name: '2'}, {name: '2.2'}, {name: '2.2.1'}]}}" |
64 | | - defaultValueUniqueField="{{'name'}}" |
65 | | - autoSelect="{{true}}" |
66 | | - initColumnSelectedIndex |
67 | | - disabled="{{false}}" |
68 | | - bindchange="pickerChange" |
69 | | - bindcancel="pickerCancel" |
70 | | - bindcolumnchange="pickerColumnchange" |
71 | | - data-picker="picker_1"> |
72 | | - <view class="picker"> |
73 | | - 当前选择:<view wx:for="{{result_1}}" wx:key="index">{{item['name']}}</view> |
74 | | - </view> |
75 | | -</comp> |
76 | | - |
77 | | -<comp |
78 | | - sourceData="{{sourceData_2}}" |
79 | | - steps="{{2}}" |
80 | | - shownFieldName="{{'name'}}" |
81 | | - subsetFieldName="{{'nextLevel'}}" |
82 | | - otherNeedFieldsName="{{['code']}}" |
83 | | - defaultValue="{{[{code: '0110'}, {code: '011002'}]}}" |
84 | | - defaultValueUniqueField="{{'code'}}" |
85 | | - autoSelect="{{true}}" |
86 | | - initColumnSelectedIndex |
87 | | - disabled="{{false}}" |
88 | | - bindchange="pickerChange" |
89 | | - bindcancel="pickerCancel" |
90 | | - bindcolumnchange="pickerColumnchange" |
91 | | - data-picker="picker_2"> |
92 | | - <view class="picker"> |
93 | | - 当前选择:<view wx:for="{{result_2}}" wx:key="index">{{item['name']}}</view> |
94 | | - </view> |
95 | | -</comp> |
96 | | -``` |
97 | | - |
98 | | -```js |
99 | | -Page({ |
100 | | - /** |
101 | | - * 页面的初始数据 |
102 | | - */ |
103 | | - data: { |
104 | | - result_1: [], |
105 | | - result_2: [], |
106 | | - sourceData_1: [ |
107 | | - { |
108 | | - id: 'id-1', |
109 | | - name: '1', |
110 | | - sonValue: [ |
111 | | - { |
112 | | - id: 'id-11', |
113 | | - name: '1.1', |
114 | | - sonValue: [ |
115 | | - { id: 'id-111', name: '1.1.1' }, |
116 | | - { id: 'id-112', name: '1.1.2' } |
117 | | - ] |
118 | | - }, |
119 | | - { |
120 | | - id: 'id-12', |
121 | | - name: '1.2', |
122 | | - sonValue: [ |
123 | | - { id: 'id-121', name: '1.2.1' }, |
124 | | - { id: 'id-122', name: '1.2.2' } |
125 | | - ] |
126 | | - } |
127 | | - ] |
128 | | - }, |
129 | | - { |
130 | | - id: 'id-2', |
131 | | - name: '2', |
132 | | - sonValue: [ |
133 | | - { |
134 | | - id: 'id-21', |
135 | | - name: '2.1', |
136 | | - sonValue: [ |
137 | | - { id: 'id-211', name: '2.1.1' }, |
138 | | - { id: 'id-212', name: '2.1.2' } |
139 | | - ] |
140 | | - }, |
141 | | - { |
142 | | - id: 'id-22', |
143 | | - name: '2.2', |
144 | | - sonValue: [ |
145 | | - { id: 'id-221', name: '2.2.1' }, |
146 | | - { id: 'id-222', name: '2.2.2' } |
147 | | - ] |
148 | | - } |
149 | | - ] |
150 | | - } |
151 | | - ], |
152 | | - sourceData_2: [ |
153 | | - { name: '河北', code: '0311', nextLevel: [{ name: '石家庄', code: '031101' }, { name: '保定', code: '031102' }]}, |
154 | | - { name: '北京', code: '0110', nextLevel: [{ name: '朝阳', code: '011001' }, { name: '海淀', code: '011002' }]}, |
155 | | - ] |
156 | | - }, |
157 | | - /** |
158 | | - * Picker用户点击确认时触发 |
159 | | - * |
160 | | - * @param {Object} e pickerChange的事件对象 |
161 | | - * @param {Object} e.detail.selectedIndex 用户选择的数据在数组中所在的下标 |
162 | | - * @param {Object} e.detail.selectedArray 用户选择的数据 |
163 | | - */ |
164 | | - pickerChange(e) { |
165 | | - const { picker } = e.currentTarget.dataset |
166 | | - const { selectedIndex, selectedArray } = e.detail |
167 | | - const list = { |
168 | | - picker_1: 'result_1', |
169 | | - picker_2: 'result_2', |
170 | | - } |
171 | | - console.log('多级联动结果:', selectedIndex, selectedArray) |
172 | | - const change = {} |
173 | | - change[list[picker]] = selectedArray |
174 | | - this.setData(change) |
175 | | - }, |
176 | | - /** |
177 | | - * Picker用户点击取消时触发 |
178 | | - * |
179 | | - * @param {Object} e pickerCancel的事件对象 |
180 | | - * @param {Object} e.detail 是原生Picker组件的bindcancel触发时的事件对象e |
181 | | - */ |
182 | | - pickerCancel(e) { |
183 | | - console.log(e) |
184 | | - }, |
185 | | - /** |
186 | | - * Picker用户滑动某一列的值改变时触发 |
187 | | - * |
188 | | - * @param {Object} e pickerColumnchange的事件对象 |
189 | | - * @param {Object} e.detail 是原生Picker组件的bindcolumnchange触发时的事件对象e |
190 | | - */ |
191 | | - pickerColumnchange(e) { |
192 | | - console.log(e) |
193 | | - }, |
194 | | -}) |
195 | | -``` |
| 38 | + - `sourceData`为源数组,是一个数组对象结构的集合,`sourceData`有几维,Picker就可以有几阶。 |
| 39 | + - `steps`,你需要明确指定Picker的阶数,比如三级联动则设置`steps: 3`。 |
| 40 | + - 需要注意的是,比如`steps`设置了`3`,那么`sourceData`务必要满足这个阶数。 |
| 41 | + - `initColumnSelectedIndex`属性启用后,开发者调试工具上会有失效情况,但是真机目前没有发现问题,所以是否开启请开发者自行决定。 |
| 42 | + - `bindchange`触发的事件对象: |
| 43 | + - `selectedIndex`:Picker选择项的索引数组; |
| 44 | + - `selectedArray`:Picker选择项的值数组; |
| 45 | + - 本组件的有些方法和属性与微信原生API的行为一致,比如:`bindchange`,`bindcancel`,`bindcolumnchange`,`disabled`。具体可以查看源码。 |
| 46 | + |
| 47 | +## 使用方法 |
| 48 | + |
| 49 | +1. 安装`miniprogram-picker`包。 |
| 50 | + |
| 51 | + > ```bash |
| 52 | + > npm install miniprogram-picker --production |
| 53 | + > ``` |
| 54 | +
|
| 55 | +2. 点击微信开发者工具中的菜单栏:工具 --> 构建 npm。此时你会发现项目中多出一个`miniprogram_npm`目录,里面有编译过的`miniprogram-picker`。 |
| 56 | +
|
| 57 | +3. `.json`中引入`miniprogram-picker`第三方组件。使用方法与使用自己封装的组件相同,只不过不需要写具体路径了,很方便。 |
| 58 | +
|
| 59 | + ```json |
| 60 | + { |
| 61 | + "usingComponents": { |
| 62 | + "miniprogram-picker": "miniprogram-picker" |
| 63 | + } |
| 64 | + } |
| 65 | + ``` |
| 66 | +
|
| 67 | +4. `.wxml`中使用`miniprogram-picker`。我这里给出了两个小例子,第一个是三级联动,第二个是两级联动。具体属性和事件方法可以参考API。 |
| 68 | + |
| 69 | + > `miniprogram-picker`是没有任何样式的,具体样式开发者可以自定义,如果你熟悉`slot`的用法那就更好了,具体参考[小程序组件wxml的slot](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html)。 |
| 70 | +
|
| 71 | + ```xml |
| 72 | + <miniprogram-picker |
| 73 | + sourceData="{{sourceData_1}}" |
| 74 | + steps="{{3}}" |
| 75 | + shownFieldName="{{'name'}}" |
| 76 | + subsetFieldName="{{'sonValue'}}" |
| 77 | + otherNeedFieldsName="{{['id', 'other']}}" |
| 78 | + defaultValue="{{[{name: '2'}, {name: '2.2'}, {name: '2.2.1'}]}}" |
| 79 | + defaultValueUniqueField="{{'name'}}" |
| 80 | + autoSelect="{{true}}" |
| 81 | + initColumnSelectedIndex |
| 82 | + disabled="{{false}}" |
| 83 | + bindchange="pickerChange" |
| 84 | + bindcancel="pickerCancel" |
| 85 | + bindcolumnchange="pickerColumnchange" |
| 86 | + data-picker="picker_1"> |
| 87 | + <view class="picker"> |
| 88 | + 当前选择:<view wx:for="{{result_1}}" wx:key="index">{{item['name']}}</view> |
| 89 | + </view> |
| 90 | + </miniprogram-picker> |
| 91 | + |
| 92 | + <miniprogram-picker |
| 93 | + sourceData="{{sourceData_2}}" |
| 94 | + steps="{{2}}" |
| 95 | + shownFieldName="{{'name'}}" |
| 96 | + subsetFieldName="{{'nextLevel'}}" |
| 97 | + otherNeedFieldsName="{{['code']}}" |
| 98 | + defaultValue="{{[{code: '0110'}, {code: '011002'}]}}" |
| 99 | + defaultValueUniqueField="{{'code'}}" |
| 100 | + autoSelect="{{true}}" |
| 101 | + initColumnSelectedIndex |
| 102 | + disabled="{{false}}" |
| 103 | + bindchange="pickerChange" |
| 104 | + bindcancel="pickerCancel" |
| 105 | + bindcolumnchange="pickerColumnchange" |
| 106 | + data-picker="picker_2"> |
| 107 | + <view class="picker"> |
| 108 | + 当前选择:<view wx:for="{{result_2}}" wx:key="index">{{item['name']}}</view> |
| 109 | + </view> |
| 110 | + </miniprogram-picker> |
| 111 | + ``` |
| 112 | + |
| 113 | +5. `.js`中设置`sourceData`和监听`pickerChange`事件等。 |
| 114 | + |
| 115 | + ```js |
| 116 | + Page({ |
| 117 | + /** |
| 118 | + * 页面的初始数据 |
| 119 | + */ |
| 120 | + data: { |
| 121 | + result_1: [], |
| 122 | + result_2: [], |
| 123 | + sourceData_1: [ |
| 124 | + { |
| 125 | + id: 'id-1', |
| 126 | + name: '1', |
| 127 | + sonValue: [ |
| 128 | + { |
| 129 | + id: 'id-11', |
| 130 | + name: '1.1', |
| 131 | + sonValue: [ |
| 132 | + { id: 'id-111', name: '1.1.1' }, |
| 133 | + { id: 'id-112', name: '1.1.2' } |
| 134 | + ] |
| 135 | + }, |
| 136 | + { |
| 137 | + id: 'id-12', |
| 138 | + name: '1.2', |
| 139 | + sonValue: [ |
| 140 | + { id: 'id-121', name: '1.2.1' }, |
| 141 | + { id: 'id-122', name: '1.2.2' } |
| 142 | + ] |
| 143 | + } |
| 144 | + ] |
| 145 | + }, |
| 146 | + { |
| 147 | + id: 'id-2', |
| 148 | + name: '2', |
| 149 | + sonValue: [ |
| 150 | + { |
| 151 | + id: 'id-21', |
| 152 | + name: '2.1', |
| 153 | + sonValue: [ |
| 154 | + { id: 'id-211', name: '2.1.1' }, |
| 155 | + { id: 'id-212', name: '2.1.2' } |
| 156 | + ] |
| 157 | + }, |
| 158 | + { |
| 159 | + id: 'id-22', |
| 160 | + name: '2.2', |
| 161 | + sonValue: [ |
| 162 | + { id: 'id-221', name: '2.2.1' }, |
| 163 | + { id: 'id-222', name: '2.2.2' } |
| 164 | + ] |
| 165 | + } |
| 166 | + ] |
| 167 | + } |
| 168 | + ], |
| 169 | + sourceData_2: [ |
| 170 | + { name: '河北', code: '0311', nextLevel: [{ name: '石家庄', code: '031101' }, { name: '保定', code: '031102' }]}, |
| 171 | + { name: '北京', code: '0110', nextLevel: [{ name: '朝阳', code: '011001' }, { name: '海淀', code: '011002' }]}, |
| 172 | + ] |
| 173 | + }, |
| 174 | + /** |
| 175 | + * Picker用户点击确认时触发 |
| 176 | + * |
| 177 | + * @param {Object} e pickerChange的事件对象 |
| 178 | + * @param {Object} e.detail.selectedIndex 用户选择的数据在数组中所在的下标 |
| 179 | + * @param {Object} e.detail.selectedArray 用户选择的数据 |
| 180 | + */ |
| 181 | + pickerChange(e) { |
| 182 | + const { picker } = e.currentTarget.dataset |
| 183 | + const { selectedIndex, selectedArray } = e.detail |
| 184 | + const list = { |
| 185 | + picker_1: 'result_1', |
| 186 | + picker_2: 'result_2', |
| 187 | + } |
| 188 | + console.log('多级联动结果:', selectedIndex, selectedArray) |
| 189 | + const change = {} |
| 190 | + change[list[picker]] = selectedArray |
| 191 | + this.setData(change) |
| 192 | + }, |
| 193 | + /** |
| 194 | + * Picker用户点击取消时触发 |
| 195 | + * |
| 196 | + * @param {Object} e pickerCancel的事件对象 |
| 197 | + * @param {Object} e.detail 是原生Picker组件的bindcancel触发时的事件对象e |
| 198 | + */ |
| 199 | + pickerCancel(e) { |
| 200 | + console.log(e) |
| 201 | + }, |
| 202 | + /** |
| 203 | + * Picker用户滑动某一列的值改变时触发 |
| 204 | + * |
| 205 | + * @param {Object} e pickerColumnchange的事件对象 |
| 206 | + * @param {Object} e.detail 是原生Picker组件的bindcolumnchange触发时的事件对象e |
| 207 | + */ |
| 208 | + pickerColumnchange(e) { |
| 209 | + console.log(e) |
| 210 | + }, |
| 211 | + }) |
| 212 | + ``` |
| 213 | + |
| 214 | +6. `.wxss`中简单设置样式。 |
| 215 | + |
| 216 | + ```css |
| 217 | + .picker { |
| 218 | + display: flex; |
| 219 | + flex-direction: row; |
| 220 | + align-items: center; |
| 221 | + margin: 10rpx 0; |
| 222 | + padding: 10rpx 0; |
| 223 | + background-color: #DEECE2; |
| 224 | + font-size: 28rpx; |
| 225 | + } |
| 226 | + .picker view { |
| 227 | + padding: 2rpx 10rpx; |
| 228 | + margin-left: 10rpx; |
| 229 | + margin-right: 10rpx; |
| 230 | + border-bottom: 2rpx solid aqua; |
| 231 | + } |
| 232 | + ``` |
| 233 | + |
196 | 234 |
|
197 | 235 | ## 帮助 |
198 | 236 |
|
199 | | -- 欢迎提Issue,若是代码有bug或者你不明白的地方,我会尽快解决。 |
200 | | -- 若有feature需要实现,可以Issue留言。 |
201 | | -- 若是觉得喜欢,欢迎star。 |
| 237 | +- 欢迎提Issue,若是代码有bug或者你不明白的地方,我会尽快解决的。 |
| 238 | +- 若有feature需要实现,可以Issue留言,若是喜欢,欢迎star。感谢你的支持。 |
0 commit comments