@fox-js/phone-skills 4.0.1-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +30 -0
  2. package/foxui/SKILL.md +442 -0
  3. package/foxui/references/fox-action-sheet/doc.md +74 -0
  4. package/foxui/references/fox-actionsheet-item/doc.md +499 -0
  5. package/foxui/references/fox-animate/doc.md +66 -0
  6. package/foxui/references/fox-audio/doc.md +76 -0
  7. package/foxui/references/fox-avatar/doc.md +70 -0
  8. package/foxui/references/fox-back-top/doc.md +69 -0
  9. package/foxui/references/fox-badge/doc.md +72 -0
  10. package/foxui/references/fox-barrage/doc.md +116 -0
  11. package/foxui/references/fox-button/doc.md +203 -0
  12. package/foxui/references/fox-calendar/doc.md +346 -0
  13. package/foxui/references/fox-calendar-item/doc.md +331 -0
  14. package/foxui/references/fox-cascader/doc.md +78 -0
  15. package/foxui/references/fox-cascader-item/doc.md +710 -0
  16. package/foxui/references/fox-cell/doc.md +74 -0
  17. package/foxui/references/fox-checkbox-item/doc.md +387 -0
  18. package/foxui/references/fox-circle-progress/doc.md +65 -0
  19. package/foxui/references/fox-collapse/doc.md +71 -0
  20. package/foxui/references/fox-count-down/doc.md +78 -0
  21. package/foxui/references/fox-count-up/doc.md +178 -0
  22. package/foxui/references/fox-date-item/doc.md +437 -0
  23. package/foxui/references/fox-date-picker/doc.md +438 -0
  24. package/foxui/references/fox-dialog/doc.md +242 -0
  25. package/foxui/references/fox-divider/doc.md +149 -0
  26. package/foxui/references/fox-domain-provider/doc.md +93 -0
  27. package/foxui/references/fox-drag/doc.md +64 -0
  28. package/foxui/references/fox-dropdown/doc.md +138 -0
  29. package/foxui/references/fox-elevator/doc.md +66 -0
  30. package/foxui/references/fox-ellipsis/doc.md +69 -0
  31. package/foxui/references/fox-empty/doc.md +67 -0
  32. package/foxui/references/fox-fixed-nav/doc.md +72 -0
  33. package/foxui/references/fox-floating-button/doc.md +142 -0
  34. package/foxui/references/fox-grid/doc.md +69 -0
  35. package/foxui/references/fox-group/doc.md +295 -0
  36. package/foxui/references/fox-icon/doc.md +65 -0
  37. package/foxui/references/fox-image/doc.md +75 -0
  38. package/foxui/references/fox-image-preview/doc.md +79 -0
  39. package/foxui/references/fox-indicator/doc.md +70 -0
  40. package/foxui/references/fox-infinite-loading/doc.md +74 -0
  41. package/foxui/references/fox-input-item/doc.md +210 -0
  42. package/foxui/references/fox-input-number/doc.md +199 -0
  43. package/foxui/references/fox-input-number-item/doc.md +213 -0
  44. package/foxui/references/fox-item/doc.md +207 -0
  45. package/foxui/references/fox-layout/doc.md +273 -0
  46. package/foxui/references/fox-link-item/doc.md +158 -0
  47. package/foxui/references/fox-list/doc.md +71 -0
  48. package/foxui/references/fox-mapping/doc.md +251 -0
  49. package/foxui/references/fox-menu/doc.md +425 -0
  50. package/foxui/references/fox-message-box/doc.md +200 -0
  51. package/foxui/references/fox-money-item/doc.md +174 -0
  52. package/foxui/references/fox-more-button/doc.md +208 -0
  53. package/foxui/references/fox-navbar/doc.md +75 -0
  54. package/foxui/references/fox-notice-bar/doc.md +71 -0
  55. package/foxui/references/fox-notify/doc.md +72 -0
  56. package/foxui/references/fox-number-keyboard/doc.md +77 -0
  57. package/foxui/references/fox-over-lay/doc.md +70 -0
  58. package/foxui/references/fox-page/doc.md +76 -0
  59. package/foxui/references/fox-pagination/doc.md +73 -0
  60. package/foxui/references/fox-picker/doc.md +668 -0
  61. package/foxui/references/fox-picker-item/doc.md +389 -0
  62. package/foxui/references/fox-popover/doc.md +70 -0
  63. package/foxui/references/fox-popover-dialog/doc.md +113 -0
  64. package/foxui/references/fox-popup/doc.md +88 -0
  65. package/foxui/references/fox-price/doc.md +67 -0
  66. package/foxui/references/fox-progress/doc.md +74 -0
  67. package/foxui/references/fox-pull-refresh/doc.md +77 -0
  68. package/foxui/references/fox-radio-item/doc.md +384 -0
  69. package/foxui/references/fox-range/doc.md +65 -0
  70. package/foxui/references/fox-rate/doc.md +141 -0
  71. package/foxui/references/fox-rate-item/doc.md +137 -0
  72. package/foxui/references/fox-rolling-provider/doc.md +87 -0
  73. package/foxui/references/fox-search-bar/doc.md +91 -0
  74. package/foxui/references/fox-short-password/doc.md +78 -0
  75. package/foxui/references/fox-side-nav-bar/doc.md +68 -0
  76. package/foxui/references/fox-signature/doc.md +202 -0
  77. package/foxui/references/fox-skeleton/doc.md +73 -0
  78. package/foxui/references/fox-steps/doc.md +162 -0
  79. package/foxui/references/fox-steps-bar/doc.md +610 -0
  80. package/foxui/references/fox-sticky/doc.md +68 -0
  81. package/foxui/references/fox-swipe/doc.md +176 -0
  82. package/foxui/references/fox-swiper/doc.md +254 -0
  83. package/foxui/references/fox-switch/doc.md +162 -0
  84. package/foxui/references/fox-switch-item/doc.md +190 -0
  85. package/foxui/references/fox-tabbar/doc.md +63 -0
  86. package/foxui/references/fox-table/doc.md +640 -0
  87. package/foxui/references/fox-tabs/doc.md +67 -0
  88. package/foxui/references/fox-tabs-bar/doc.md +533 -0
  89. package/foxui/references/fox-tag/doc.md +213 -0
  90. package/foxui/references/fox-text/doc.md +84 -0
  91. package/foxui/references/fox-textarea-item/doc.md +106 -0
  92. package/foxui/references/fox-toast/doc.md +149 -0
  93. package/foxui/references/fox-tour/doc.md +89 -0
  94. package/foxui/references/fox-trend-arrow/doc.md +72 -0
  95. package/foxui/references/fox-uploader/doc.md +96 -0
  96. package/foxui/references/fox-video/doc.md +245 -0
  97. package/foxui/references/fox-water-mark/doc.md +81 -0
  98. package/package.json +21 -0
@@ -0,0 +1,668 @@
1
+ <!--
2
+ * @Author: 江成
3
+ * @Date: 2026-04-27 00:37:28
4
+ * @LastEditors: 江成
5
+ * @LastEditTime: 2026-05-12 22:33:21
6
+ -->
7
+ ---
8
+ title: Picker 组件使用规范
9
+ impact: HIGH
10
+ type: capability
11
+ description: 提供多个选型集合供用户选择,支持单列选择和多列级联,通常与弹出层配合使用
12
+ tags: [foxui, fox-picker, FoxPicker]
13
+ version: "4.0.0"
14
+ author: jiangcheng
15
+ related: ["fox-js","fox-cell","fox-switch-item","fox-button"]
16
+ ---
17
+
18
+ # Picker 组件使用规范
19
+
20
+ ## 1. 核心职责 (Core Responsibility)
21
+ Picker 是 foxui 中用于 **提供多个选型集合供用户选择,支持单列选择和多列级联,通常与弹出层配合使用** 的标准组件。
22
+ - **基于**: NutUI `nut-picker` 进行了二次封装 (若为纯自研组件则填 "自定义开发")
23
+ - **核心增强**: 基于 NutUI 组件二次封装、支持 v-model 双向绑定、支持插槽扩展自定义内容
24
+ - **适用场景**: 提供多个选型集合供用户选择,支持单列选择和多列级联,通常与弹出层配合使用
25
+
26
+ > 💡 **关键原则**: 在所有 提供多个选型集合供用户选择,支持单列选择和多列级联,通常与弹出层配合使用 中,**必须**优先使用此组件,禁止直接使用原生 NutUI 组件。
27
+
28
+ ---
29
+
30
+ ## 2. 关键 API 说明 (Key API)
31
+
32
+ ### 2.1 Props 属性
33
+
34
+ | 属性名 | 类型 | 必填 | 默认值 | 说明 |
35
+ | :--- | :--- | :---: | :---: | :--- |
36
+ | `v-model` | 值 | Array,Boolean,String,Number | false |
37
+ | `v-model:visible` | 是否可见 | Boolean | false |
38
+ | `title` | 设置标题 | String | - |
39
+ | `cancel-text` | 取消按钮文案 | String | 取消 |
40
+ | `confirm-text` | 确定按钮文案 | String | 确定 |
41
+ | `source` | 数据源 | string / array/ function | — |
42
+ | `source-filter` | 数据源过滤器 | function | — |
43
+ | `param` | 请求参数配置数据源api使用 | record<string,any> | — |
44
+ | `valueType` | 值的类型text:item.text,value:item.value,item:item | String | "value" |
45
+ | `text-key` | 指定异构数据源的text key | String | "text" |
46
+ | `text-key` | 指定异构数据源的value key | String | "value" |
47
+ | `children-key` | 指定异构数据源的children key | String | "children" |
48
+ | `three-dimensional` | 是否开启3D效果 | Boolean | true |
49
+ | `swipe-duration` | 惯性滚动时长 | Number、String | 1000 |
50
+ | `visible-item-count` | 可见item数量必须为奇数 | Number、String | 7 |
51
+ | `teleport` | 指定挂载节点 | String | "body" |
52
+ | `close-on-click-overlay` | 点击蒙层是否关闭对话框 | Boolean | false |
53
+ | `lock-scroll` | 背景是否锁定 | Boolean | false |
54
+ | `poppable` | 是否弹出 | Boolean | true |
55
+
56
+ ### 2.2 Events 事件
57
+
58
+ | 事件名 | 类型 | 说明 |
59
+ | :--- | :--- | :--- |
60
+ | `close` | 关闭弹窗时触发 | event: Event |
61
+ | `confirm` | 点击确认时候触发 | event: Event |
62
+ | `change` | 改变时触发 | val |
63
+
64
+ ### 2.3 Methods 方法
65
+
66
+ | 方法名 | 参数 | 说明 |
67
+ | :--- | :--- | :--- |
68
+
69
+
70
+ ### 2.4 Slots 插槽
71
+
72
+ | 插槽名 | 说明 |
73
+ | :--- | :--- |
74
+ | `default` | 自定义滑动数据底部区域 |
75
+ | `top` | 自定义滑动数据顶部区域 |
76
+
77
+ ## 3. 例子 (Examples)
78
+
79
+ ## 代码演示
80
+
81
+ ### 基础用法
82
+
83
+ ```html
84
+ <fox-cell title="请选择城市" :desc="desc(val)" @click="open(1)"></fox-cell>
85
+ <fox-picker v-model="val" v-model:visible="show" :source="m_str_items" title="城市选择" @confirm="confirm" @close="close">
86
+ </fox-picker>
87
+ ```
88
+
89
+ ```javascript
90
+ <script>
91
+ export default createDemo({
92
+ setup() {
93
+ // 数据
94
+ const data = reactive({
95
+ m_str_items: ['南京', '无锡', '海北藏族自治区', '北京', '连云港', '浙江省', '江苏省'],
96
+ val: '浙江市',
97
+ show: false,
98
+ })
99
+
100
+ // 方法
101
+ const methods = {
102
+ // open picker
103
+ open(id: number) {
104
+ if (id == 1) {
105
+ data.show = true
106
+ } else {
107
+ let dataAny = data as any
108
+ dataAny[`show${id}`] = true
109
+ }
110
+ },
111
+ // close picker
112
+ close() {
113
+ console.info('close')
114
+ },
115
+ // confirm action
116
+ confirm() {
117
+ console.info('confirm')
118
+ },
119
+ // 显示描述
120
+ desc(val: unknown) {
121
+ if (Array.isArray(val)) {
122
+ if (val.length == 0) {
123
+ return ''
124
+ }
125
+ return JSON.stringify(val)
126
+ } else if (typeof val == 'object') {
127
+ return JSON.stringify(val)
128
+ } else {
129
+ return `${val}`
130
+ }
131
+ }
132
+ }
133
+
134
+ return {
135
+ ...toRefs(data),
136
+ ...methods
137
+ };
138
+ }
139
+ });
140
+ </script>
141
+ ```
142
+
143
+ ### 平铺样式
144
+
145
+ ```
146
+ <h2>平铺样式</h2>
147
+ <fox-cell title="请选择城市" :desc="desc(val2)" @click="open(2)"></fox-cell>
148
+ <fox-picker
149
+ v-model="val2"
150
+ v-model:visible="show2"
151
+ :source="m_items"
152
+ :three-dimensional="false"
153
+ title="城市选择"
154
+ @confirm="confirm"
155
+ @close="close"
156
+ >
157
+ </fox-picker>
158
+
159
+ ```
160
+
161
+ 设置`three-dimensional`属性为false
162
+
163
+ ### 平铺样式
164
+
165
+ ```
166
+ <h2>平铺样式</h2>
167
+ <fox-cell title="请选择城市" :desc="desc(val2)" @click="open(2)"></fox-cell>
168
+ <fox-picker
169
+ v-model="val2"
170
+ v-model:visible="show2"
171
+ :source="m_items"
172
+ :three-dimensional="false"
173
+ title="城市选择"
174
+ @confirm="confirm"
175
+ @close="close"
176
+ >
177
+ </fox-picker>
178
+
179
+ ```
180
+
181
+ 设置`three-dimensional`属性为false
182
+
183
+ ### 显示数量设置
184
+
185
+ ```
186
+ <h2>显示数量设置</h2>
187
+ <fox-cell title="请选择城市" :desc="desc(val3)" @click="open(3)"></fox-cell>
188
+ <fox-picker
189
+ v-model="val3"
190
+ v-model:visible="show3"
191
+ :source="m_items"
192
+ :three-dimensional="false"
193
+ :visible-item-count="13"
194
+ title="城市选择"
195
+ @confirm="confirm"
196
+ @close="close">
197
+ </fox-picker>
198
+
199
+ ```
200
+ 前提是设置`three-dimensional`属性为false, `visible-item-count`属性为可见item的数量,必须为奇数
201
+
202
+ ### 多列样式
203
+
204
+ ```html
205
+ <fox-cell title="请选择时间" :desc="desc(val2)" @click="open(2)"></fox-cell>
206
+ <fox-picker v-model="val2" v-model:visible="show2" :source="m_str_multi_items" title="多列选择"
207
+ @confirm="confirm" @close="close">
208
+ </fox-picker>
209
+ ```
210
+
211
+ ```javascript
212
+ <script>
213
+ export default createDemo({
214
+ setup() {
215
+ // 数据
216
+ const data = reactive({
217
+ m_str_multi_items: [
218
+ ['周一', '周二', '周三', '周四', '周五'],
219
+ ['上午', '下午', '晚上']
220
+ ],
221
+ val2: [],
222
+ show2: false,
223
+ })
224
+
225
+ // 方法
226
+ const methods = {
227
+ // open picker
228
+ open(id: number) {
229
+ if (id == 1) {
230
+ data.show = true
231
+ } else {
232
+ let dataAny = data as any
233
+ dataAny[`show${id}`] = true
234
+ }
235
+ },
236
+ // close picker
237
+ close() {
238
+ console.info('close')
239
+ },
240
+ // confirm action
241
+ confirm() {
242
+ console.info('confirm')
243
+ },
244
+ // 显示描述
245
+ desc(val: unknown) {
246
+ if (Array.isArray(val)) {
247
+ if (val.length == 0) {
248
+ return ''
249
+ }
250
+ return JSON.stringify(val)
251
+ } else if (typeof val == 'object') {
252
+ return JSON.stringify(val)
253
+ } else {
254
+ return `${val}`
255
+ }
256
+ }
257
+ }
258
+
259
+ return {
260
+ ...toRefs(data),
261
+ ...methods
262
+ };
263
+ }
264
+ });
265
+ </script>
266
+ ```
267
+
268
+ ### 多级联动
269
+
270
+ ```html
271
+ <fox-cell title="请选择地址" :desc="desc(val3)" @click="open(3)"></fox-cell>
272
+ <fox-picker v-model="val3" v-model:visible="show3" :source="m_address" title="地址选择" @confirm="confirm"></fox-picker>
273
+ ```
274
+
275
+ ```javascript
276
+ <script>
277
+ export default createDemo({
278
+ setup() {
279
+ // 数据
280
+ const data = reactive({
281
+ m_address: [
282
+ {
283
+ text: '浙江',
284
+ value: '浙江',
285
+ children: [
286
+ {
287
+ text: '杭州',
288
+ value: '杭州',
289
+ children: [
290
+ { text: '西湖区', value: '西湖区' },
291
+ { text: '余杭区', value: '余杭区' }
292
+ ]
293
+ },
294
+ {
295
+ text: '温州',
296
+ value: '温州',
297
+ children: [
298
+ { text: '鹿城区', value: '鹿城区' },
299
+ { text: '瓯海区', value: '瓯海区' }
300
+ ]
301
+ }
302
+ ]
303
+ },
304
+ {
305
+ text: '福建',
306
+ value: '福建',
307
+ children: [
308
+ {
309
+ text: '福州',
310
+ value: '福州',
311
+ children: [
312
+ { text: '鼓楼区', value: '鼓楼区' },
313
+ { text: '台江区', value: '台江区' }
314
+ ]
315
+ },
316
+ {
317
+ text: '厦门',
318
+ value: '厦门',
319
+ children: [
320
+ { text: '思明区', value: '思明区' },
321
+ { text: '海沧区', value: '海沧区' }
322
+ ]
323
+ }
324
+ ]
325
+ }
326
+ ],
327
+ val3: [],
328
+ show3: false,
329
+ })
330
+
331
+ // 方法
332
+ const methods = {
333
+ // open picker
334
+ open(id: number) {
335
+ if (id == 1) {
336
+ data.show = true
337
+ } else {
338
+ let dataAny = data as any
339
+ dataAny[`show${id}`] = true
340
+ }
341
+ },
342
+ // close picker
343
+ close() {
344
+ console.info('close')
345
+ },
346
+ // confirm action
347
+ confirm() {
348
+ console.info('confirm')
349
+ },
350
+ // 显示描述
351
+ desc(val: unknown) {
352
+ if (Array.isArray(val)) {
353
+ if (val.length == 0) {
354
+ return ''
355
+ }
356
+ return JSON.stringify(val)
357
+ } else if (typeof val == 'object') {
358
+ return JSON.stringify(val)
359
+ } else {
360
+ return `${val}`
361
+ }
362
+ }
363
+ }
364
+
365
+ return {
366
+ ...toRefs(data),
367
+ ...methods
368
+ };
369
+ }
370
+ });
371
+ </script>
372
+ ```
373
+
374
+ ### 返回类型text
375
+
376
+ ```html
377
+ <fox-cell title="请选择城市" :desc="desc(val4)" @click="open(4)"></fox-cell>
378
+ <fox-picker v-model="val4" v-model:visible="show4" :source="m_items" title="城市选择" value-type="text" @confirm="confirm" @close="close" >
379
+ </fox-picker>
380
+ ```
381
+
382
+ ```javascript
383
+ <script>
384
+ export default createDemo({
385
+ setup() {
386
+ // 数据
387
+ const data = reactive({
388
+ m_items: [
389
+ { text: '南京', value: '01' },
390
+ { text: '无锡', value: '02' },
391
+ { text: '海北藏族自治区', value: '03' },
392
+ { text: '北京', value: '04' },
393
+ { text: '连云港', value: '05' },
394
+ { text: '浙江省', value: '06' },
395
+ { text: '江苏省', value: '07' }
396
+ ],
397
+ val4: [],
398
+ show4: false,
399
+ })
400
+
401
+ // 方法
402
+ const methods = {
403
+ // open picker
404
+ open(id: number) {
405
+ if (id == 1) {
406
+ data.show = true
407
+ } else {
408
+ let dataAny = data as any
409
+ dataAny[`show${id}`] = true
410
+ }
411
+ },
412
+ // close picker
413
+ close() {
414
+ console.info('close')
415
+ },
416
+ // confirm action
417
+ confirm() {
418
+ console.info('confirm')
419
+ },
420
+ // 显示描述
421
+ desc(val: unknown) {
422
+ if (Array.isArray(val)) {
423
+ if (val.length == 0) {
424
+ return ''
425
+ }
426
+ return JSON.stringify(val)
427
+ } else if (typeof val == 'object') {
428
+ return JSON.stringify(val)
429
+ } else {
430
+ return `${val}`
431
+ }
432
+ }
433
+ }
434
+
435
+ return {
436
+ ...toRefs(data),
437
+ ...methods
438
+ };
439
+ }
440
+ });
441
+ </script>
442
+ ```
443
+
444
+ ### 返回类型value
445
+
446
+ ```html
447
+ <fox-cell title="请选择城市" :desc="desc(val5)" @click="open(5)"></fox-cell>
448
+ <fox-picker v-model="val5" v-model:visible="show5" :source="m_items" title="城市选择" value-type="value" @confirm="confirm" @close="close">
449
+ </fox-picker>
450
+ ```
451
+
452
+ ```javascript
453
+ <script>
454
+ export default createDemo({
455
+ setup() {
456
+ // 数据
457
+ const data = reactive({
458
+ m_items: [
459
+ { text: '南京', value: '01' },
460
+ { text: '无锡', value: '02' },
461
+ { text: '海北藏族自治区', value: '03' },
462
+ { text: '北京', value: '04' },
463
+ { text: '连云港', value: '05' },
464
+ { text: '浙江省', value: '06' },
465
+ { text: '江苏省', value: '07' }
466
+ ],
467
+ val5: [],
468
+ show5: false,
469
+ })
470
+
471
+ // 方法
472
+ const methods = {
473
+ // open picker
474
+ open(id: number) {
475
+ if (id == 1) {
476
+ data.show = true
477
+ } else {
478
+ let dataAny = data as any
479
+ dataAny[`show${id}`] = true
480
+ }
481
+ },
482
+ // close picker
483
+ close() {
484
+ console.info('close')
485
+ },
486
+ // confirm action
487
+ confirm() {
488
+ console.info('confirm')
489
+ },
490
+ // 显示描述
491
+ desc(val: unknown) {
492
+ if (Array.isArray(val)) {
493
+ if (val.length == 0) {
494
+ return ''
495
+ }
496
+ return JSON.stringify(val)
497
+ } else if (typeof val == 'object') {
498
+ return JSON.stringify(val)
499
+ } else {
500
+ return `${val}`
501
+ }
502
+ }
503
+ }
504
+
505
+ return {
506
+ ...toRefs(data),
507
+ ...methods
508
+ };
509
+ }
510
+ });
511
+ </script>
512
+ ```
513
+
514
+ ### 返回类型item
515
+
516
+ ```html
517
+ <fox-cell title="请选择城市" :desc="desc(val6)" @click="open(6)"></fox-cell>
518
+ <fox-picker v-model="val6" v-model:visible="show6" :source="m_items" title="城市选择" value-type="item" @confirm="confirm" @close="close"></fox-picker>
519
+ ```
520
+
521
+ ```javascript
522
+ <script>
523
+ export default createDemo({
524
+ setup() {
525
+ // 数据
526
+ const data = reactive({
527
+ m_items: [
528
+ { text: '南京', value: '01' },
529
+ { text: '无锡', value: '02' },
530
+ { text: '海北藏族自治区', value: '03' },
531
+ { text: '北京', value: '04' },
532
+ { text: '连云港', value: '05' },
533
+ { text: '浙江省', value: '06' },
534
+ { text: '江苏省', value: '07' }
535
+ ],
536
+ val6: { text: '北京', value: '04' },,
537
+ show6: false,
538
+ })
539
+
540
+ // 方法
541
+ const methods = {
542
+ // open picker
543
+ open(id: number) {
544
+ if (id == 1) {
545
+ data.show = true
546
+ } else {
547
+ let dataAny = data as any
548
+ dataAny[`show${id}`] = true
549
+ }
550
+ },
551
+ // close picker
552
+ close() {
553
+ console.info('close')
554
+ },
555
+ // confirm action
556
+ confirm() {
557
+ console.info('confirm')
558
+ },
559
+ // 显示描述
560
+ desc(val: unknown) {
561
+ if (Array.isArray(val)) {
562
+ if (val.length == 0) {
563
+ return ''
564
+ }
565
+ return JSON.stringify(val)
566
+ } else if (typeof val == 'object') {
567
+ return JSON.stringify(val)
568
+ } else {
569
+ return `${val}`
570
+ }
571
+ }
572
+ }
573
+
574
+ return {
575
+ ...toRefs(data),
576
+ ...methods
577
+ };
578
+ }
579
+ });
580
+ </script>
581
+ ```
582
+
583
+ ### 函数数据源
584
+
585
+ ```html
586
+ <fox-cell title="请选择时间" :desc="desc(val7)" @click="open(7)"></fox-cell>
587
+ <fox-picker v-model="val7" v-model:visible="show7" :source="m_func" title="时间选择" value-type="text" @confirm="confirm" @close="close"></fox-picker>
588
+ ```
589
+
590
+ ```javascript
591
+ <script>
592
+ export default createDemo({
593
+ setup() {
594
+ let m_multi_items = [
595
+ [
596
+ { text: '周一', value: '一' },
597
+ { text: '周二', value: '二' },
598
+ { text: '周三', value: '三' },
599
+ { text: '周四', value: '四' },
600
+ { text: '周五', value: '五' }
601
+ ],
602
+ [
603
+ { text: '上午', value: '上' },
604
+ { text: '下午', value: '下' },
605
+ { text: '晚上', value: '晚' }
606
+ ]
607
+ ]
608
+
609
+ // 数据
610
+ const data = reactive({
611
+ m_func: (): Promise<unknown> => {
612
+ return new Promise(resolve => {
613
+ resolve(m_multi_items)
614
+ })
615
+ },
616
+ val7: ['周五', '晚上'],
617
+ show7: false,
618
+ })
619
+
620
+ // 方法
621
+ const methods = {
622
+ // open picker
623
+ open(id: number) {
624
+ if (id == 1) {
625
+ data.show = true
626
+ } else {
627
+ let dataAny = data as any
628
+ dataAny[`show${id}`] = true
629
+ }
630
+ },
631
+ // close picker
632
+ close() {
633
+ console.info('close')
634
+ },
635
+ // confirm action
636
+ confirm() {
637
+ console.info('confirm')
638
+ },
639
+ // 显示描述
640
+ desc(val: unknown) {
641
+ if (Array.isArray(val)) {
642
+ if (val.length == 0) {
643
+ return ''
644
+ }
645
+ return JSON.stringify(val)
646
+ } else if (typeof val == 'object') {
647
+ return JSON.stringify(val)
648
+ } else {
649
+ return `${val}`
650
+ }
651
+ }
652
+ }
653
+
654
+ return {
655
+ ...toRefs(data),
656
+ ...methods
657
+ };
658
+ }
659
+ });
660
+ </script>
661
+ ```
662
+
663
+ ## 4. 相关组件 (Related Components)
664
+ - **fox-js**: 与 Picker 配合使用的相关组件
665
+ - **fox-cell**: 与 Picker 配合使用的相关组件
666
+ - **fox-switch-item**: 与 Picker 配合使用的相关组件
667
+ - **fox-button**: 与 Picker 配合使用的相关组件
668
+