121 lines
6.1 KiB
JSON
121 lines
6.1 KiB
JSON
{
|
||
"slug": "input",
|
||
"end": "vue3",
|
||
"curated": true,
|
||
"summary": "Vue 3 输入框:v-model 走 modelValue,含尺寸档位、错误文案与前后缀具名插槽。",
|
||
"usage": [
|
||
"v-model 走 modelValue 与 update:modelValue:onInput 里 emit 的是 e.target.value 字符串(Input.vue3.vue:81-83),父层不需要再接原生 input 事件。",
|
||
"focus 与 blur 事件抛的是原生事件对象而不是值(第 13-14 行用 $emit 转发 $event),要值仍然看 modelValue。",
|
||
"前后缀是 <script setup> 下的具名插槽 prefix 与 suffix,模板先用 $slots 判断存在才渲染包裹层(第 4、45 行),不写插槽就不出多余节点。",
|
||
"size 由 defineProps 声明并只认 large / default / small 三档,经 <script setup> 里的 sizeMap 映射成 kole-input-lg 或 md 或 sm 类(第 68 行),传别的值会拼出 undefined 类名。",
|
||
"type 传 password 时组件自己加明暗文切换按钮并改写真实 input 的 type(第 77-79 行的 computed resolvedType),外部传的 type 不会被改。",
|
||
"清除按钮只在 clearable、modelValue 非空、未 disabled 三者同时成立时渲染(第 18 行),清空后组件用 requestAnimationFrame 把焦点还给输入框(第 88 行)。"
|
||
],
|
||
"bestPractices": [
|
||
"错误提示要 error 与 errorText 同时给:只有 error 为 true 且 errorText 非空才渲染 .error-text(第 48 行),只传 error 只有红边框没有文案。",
|
||
"组件内部持有名为 input 的模板 ref 用于清除后聚焦(第 7、70、88 行),外部不要再给同一元素挂同名 ref,否则会互相覆盖。",
|
||
"modelValue 接受 String 或 Number(第 56 行),但 emit 出去的永远是字符串,需要数字类型请在父层转换。",
|
||
"尺寸类与 is-error、is-disabled 都由内部 classes computed 拼到 .kole-input 上(第 72-75 行),外部只需要传 prop,不要手工再拼 kole-input-lg。"
|
||
],
|
||
"a11y": [
|
||
"清除按钮与密码切换按钮都带动态 aria-label(清除、显示密码、隐藏密码,第 21、33 行),图标按钮对读屏器有名字。",
|
||
"错误态是外层的 has-error 类加 .error-text 文本(第 2、48 行),文字提示本身可读;但输入框没有 aria-invalid 与 aria-describedby 关联。",
|
||
"禁用落到底层原生 input 的 disabled 属性(第 11 行),不可聚焦也不参与表单提交。",
|
||
"前后缀插槽默认只有样式的 affix 容器,往里放按钮时要自己补 aria-label,否则读屏器得不到可操作名称。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "Vue 3 端载体是 8 个 defineProps、update:modelValue 与 focus、blur 三个 emit,以及 prefix 与 suffix 两个具名插槽(frameworks/Input.vue3.vue:55-66)。",
|
||
"table": [
|
||
{
|
||
"name": "clearable",
|
||
"type": "Boolean",
|
||
"desc": "是否可清空(契约:支持前后缀、清除按钮、数字输入、密码切换)(frameworks/Input.vue3.vue:18)"
|
||
},
|
||
{
|
||
"name": "disabled",
|
||
"type": "Boolean",
|
||
"desc": "是否禁用(frameworks/Input.vue3.vue:11)"
|
||
},
|
||
{
|
||
"name": "error",
|
||
"type": "Boolean",
|
||
"desc": "错误提示(契约:错误:边框#F5222D,下方红色12px错误提示)(frameworks/Input.vue3.vue:2)"
|
||
},
|
||
{
|
||
"name": "errorText",
|
||
"type": "String",
|
||
"desc": "错误提示文本(frameworks/Input.vue3.vue:48)"
|
||
},
|
||
{
|
||
"name": "modelValue",
|
||
"type": "String | Number",
|
||
"desc": "双向绑定值(frameworks/Input.vue3.vue:9)"
|
||
},
|
||
{
|
||
"name": "placeholder",
|
||
"type": "属性",
|
||
"desc": "透传给底层原生 input 的 placeholder(frameworks/Input.vue3.vue:10)"
|
||
},
|
||
{
|
||
"name": "size",
|
||
"type": "String",
|
||
"desc": "尺寸(契约:尺寸:Default(32px高)、Large(40px高)、Small(24p)(frameworks/Input.vue3.vue:57)"
|
||
},
|
||
{
|
||
"name": "type",
|
||
"type": "属性",
|
||
"desc": "决定原生 input 的 type;传 password 时改由 resolvedType 在明暗文间切换(frameworks/Input.vue3.vue:58,77-79)"
|
||
},
|
||
{
|
||
"name": "blur",
|
||
"type": "(val: any) => void",
|
||
"desc": "失去焦点时触发(frameworks/Input.vue3.vue:14)"
|
||
},
|
||
{
|
||
"name": "focus",
|
||
"type": "(val: any) => void",
|
||
"desc": "获得焦点时触发(frameworks/Input.vue3.vue:13)"
|
||
},
|
||
{
|
||
"name": "prefix",
|
||
"type": "插槽",
|
||
"desc": "有内容才渲染 .affix.prefix 包裹层,判断用 $slots.prefix(frameworks/Input.vue3.vue:4)"
|
||
},
|
||
{
|
||
"name": "suffix",
|
||
"type": "插槽",
|
||
"desc": "有内容才渲染 .affix.suffix 包裹层,判断用 $slots.suffix(frameworks/Input.vue3.vue:45)"
|
||
}
|
||
]
|
||
},
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/Input.vue3.vue",
|
||
"kind": "Vue 3",
|
||
"desc": "该端实现(本页 API 与用法的唯一权威来源)。"
|
||
},
|
||
{
|
||
"file": "frameworks/Input.css",
|
||
"kind": "样式",
|
||
"desc": "该组件的样式文件,类名口径以它为准。"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"input-ex-1",
|
||
"input-ex-2",
|
||
"input-ex-3",
|
||
"input-ex-4",
|
||
"input-ex-5",
|
||
"input-ex-6"
|
||
],
|
||
"notes": [
|
||
"props 声明见 frameworks/Input.vue3.vue:55-64,modelValue 在第 56 行接受 String 或 Number。",
|
||
"update:modelValue 在 frameworks/Input.vue3.vue:81-83 派发 e.target.value,clear 在第 86 行派发空串并在第 88 行重新聚焦。",
|
||
"prefix 与 suffix 插槽分别在 frameworks/Input.vue3.vue:4 与 45,均用 $slots 判断后渲染。",
|
||
"focus 与 blur 在 frameworks/Input.vue3.vue:13-14 转发原生事件对象,因此回调参数与 Vue 2 端的同名事件含义不同。",
|
||
"契约声明的驱动维度 size / state / feature 属设计词汇层,未作为 prop 写入本页。",
|
||
"placeholder 只落在原生 input 的属性位(frameworks/Input.vue3.vue:10);type 先经 resolvedType 计算再绑定(第 8 行),并额外决定密码切换按钮是否渲染(第 30 行)。"
|
||
]
|
||
}
|