80 lines
4.0 KiB
JSON
80 lines
4.0 KiB
JSON
{
|
||
"slug": "listpicker",
|
||
"end": "vue3",
|
||
"curated": true,
|
||
"summary": "Vue 3 下拉多选选择器:选项支持扁平或分组,选中项以标签回显,面板内可搜索与全选。",
|
||
"usage": [
|
||
"用 v-model 绑定数组型 modelValue,组件内部 commit 同时 emit(\"update:modelValue\") 与 emit(\"change\"),标签删除、选项勾选、全选走的是同一条回写路径(ListPicker.vue3.vue:65)。",
|
||
"options 是必填项,直接传 [{value,label}] 走扁平模式,传 [{label,children:[{value,label}]}] 自动切成分组模式(ListPicker.vue3.vue:48)。",
|
||
"想关掉面板顶部的搜索框要显式写 :filterable=\"false\",该 prop 默认为 true(ListPicker.vue3.vue:39)。",
|
||
"未选择任何项时渲染 placeholder,默认文案是「请选择」,改文案只需传 :placeholder(ListPicker.vue3.vue:40)。",
|
||
"选项对象里的 disabled:true 会让该行不可点,行上会挂 is-disabled 类(ListPicker.vue3.vue:62)。"
|
||
],
|
||
"bestPractices": [
|
||
"面板的收起监听是挂在 document 上的捕获式 click,并在 onBeforeUnmount 里成对移除;若把组件放在自身会 stopPropagation 的容器里,点击外部收起可能失效(ListPicker.vue3.vue:67)。",
|
||
"modelValue 必须始终是数组,default 为 () => [];传 null 会在模板里执行 modelValue.length 时报错(ListPicker.vue3.vue:37)。",
|
||
"关键字搜索只做 label.includes(query) 的朴素匹配,没有拼音或首字母检索,候选量大时应在业务侧预筛 options(ListPicker.vue3.vue:52)。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "本端 API 载体是 props + emit + 模板类名:defineProps 声明 modelValue/options/filterable/placeholder,defineEmits 声明 update:modelValue 与 change,无具名插槽。",
|
||
"table": [
|
||
{
|
||
"name": "modelValue",
|
||
"type": "Array",
|
||
"desc": "选中 value 数组,v-model 绑定;默认 () => []"
|
||
},
|
||
{
|
||
"name": "options",
|
||
"type": "Array",
|
||
"desc": "必填;扁平 [{value,label}] 或分组 [{label,children}],按首项有无 children 自动判定"
|
||
},
|
||
{
|
||
"name": "filterable",
|
||
"type": "Boolean",
|
||
"desc": "是否在面板顶部渲染搜索框,默认 true"
|
||
},
|
||
{
|
||
"name": "placeholder",
|
||
"type": "String",
|
||
"desc": "无选中项时的提示文案,默认「请选择」"
|
||
},
|
||
{
|
||
"name": "update:modelValue",
|
||
"type": "emit(payload: Array)",
|
||
"desc": "v-model 回写事件,载荷为新的选中 value 数组"
|
||
},
|
||
{
|
||
"name": "change",
|
||
"type": "emit(payload: Array)",
|
||
"desc": "与 update:modelValue 同载荷,便于不写 v-model 时监听"
|
||
}
|
||
]
|
||
},
|
||
"a11y": [
|
||
"触发器是 <div class=\"kole-listpicker-trigger\" @click>,既没有 role 也没有 tabindex,键盘用户无法打开面板——接入前应由业务补 button 或将触发器替换为可聚焦元素(ListPicker.vue3.vue:3)。",
|
||
"面板与选项同样是 div + @click,展开/收起状态只体现在 is-open 类上,没有 aria-expanded / aria-selected 可传达给读屏(ListPicker.vue3.vue:13)。"
|
||
],
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/ListPicker.vue3.vue",
|
||
"kind": "Vue 3 组件",
|
||
"desc": "listpicker 的 Vue 3(<script setup>)实现源码"
|
||
},
|
||
{
|
||
"file": "frameworks/ListPicker.css",
|
||
"kind": "样式",
|
||
"desc": "该组件在 PC 端共用的样式表"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"listpicker-ex-1"
|
||
],
|
||
"notes": [
|
||
"frameworks/ListPicker.vue3.vue:37 — defineProps 声明 modelValue/options/filterable/placeholder",
|
||
"frameworks/ListPicker.vue3.vue:42 — 本端 v-model 契约由 modelValue + update:modelValue 这一对命名承载",
|
||
"frameworks/ListPicker.vue3.vue:65 — 所有改动统一经 commit 双发 update:modelValue 与 change",
|
||
"frameworks/ListPicker.vue3.vue:68 — document 捕获式 click 收起面板,onBeforeUnmount 成对移除"
|
||
]
|
||
}
|