99 lines
5.1 KiB
JSON
99 lines
5.1 KiB
JSON
{
|
||
"slug": "button",
|
||
"end": "vue3",
|
||
"curated": true,
|
||
"summary": "Vue 3 按钮,6 个 props 控类型与尺寸、禁用与加载、图标,点击走 click 事件,文案可用 text 或插槽。",
|
||
"usage": [
|
||
"`<script setup>` 里 `defineProps` 声明 6 个 props,type 与 size 都靠字符串映射到类名(sizeMap 把 large 变成 btn-lg),本端无 v-model 也无 .sync。",
|
||
"点击处理在 `onClick` 里先拦再用 `emit('click', e)` 派发(click 由 `defineEmits` 声明):disabled 或 loading 为真时直接 return,父级收不到 click。",
|
||
"文案可以走 `text` prop,也可以写默认插槽;`<slot>{{ text }}</slot>` 的兜底语义让插槽内容优先。",
|
||
"icon 只接受一段 SVG path 的 d 属性字符串,模板用 `:d=\"icon\"` 内联画 16×16 图标,loading 为真时会被 spinner 通过 v-if / v-else-if 顶掉。",
|
||
"根元素是原生 `<button>`,根上的 `:disabled=\"disabled || loading\"` 让加载中也带上原生 disabled 属性,与 `defineProps` 里的两个布尔 prop 直接联动。"
|
||
],
|
||
"bestPractices": [
|
||
"type 的取值是 primary / default / text / link / danger,拼错不报错,只会拼出 `.btn-xxx` 这个不存在的类名并退化成裸按钮样式。",
|
||
"loading 会把禁用类换掉(条件是 `disabled && !loading`),所以加载中看到的是 `.is-loading` 而非禁用态样式。",
|
||
"文案用插槽时不要再把 text 重复写一遍,插槽有内容时 prop 值不再渲染。",
|
||
"本端样式写在组件内 `<style scoped>` 且用字面色值,改主题色需要动组件源码或外部覆盖,不是改 CSS 变量。"
|
||
],
|
||
"a11y": [
|
||
"根元素是真 `<button>`,`:disabled` 让它不可聚焦也不响应,读屏器会播报不可用状态。",
|
||
"加载 spinner 标了 `aria-hidden=\"true\"`,但按钮没有 `aria-busy`,读屏器只看到文字、不知道正在加载。",
|
||
"图标是纯装饰 path(无 title 元素),图标按钮要可读必须给可见文字或用 text prop 兜底。",
|
||
"`.btn:focus-visible` 的描边是 2px 半透明蓝(rgba(47,84,235,0.2)),对比度偏低,深色背景上焦点环不明显。"
|
||
],
|
||
"apiCarrier": {
|
||
"kind": "props",
|
||
"note": "Vue 3 端的 API 载体是 6 个 props(type / size / disabled / loading / icon / text)、1 个 `click` 事件与 1 个默认插槽,共 8 项。",
|
||
"table": [
|
||
{
|
||
"name": "disabled",
|
||
"type": "属性",
|
||
"desc": "与 loading 合并成原生 disabled(:disabled=\"disabled || loading\"),并在 onClick 里短路(frameworks/Button.vue3.vue:4,47)"
|
||
},
|
||
{
|
||
"name": "icon",
|
||
"type": "String",
|
||
"desc": "图标(frameworks/Button.vue3.vue:9)"
|
||
},
|
||
{
|
||
"name": "loading",
|
||
"type": "Boolean",
|
||
"desc": "是否加载中(frameworks/Button.vue3.vue:4)"
|
||
},
|
||
{
|
||
"name": "size",
|
||
"type": "属性",
|
||
"desc": "经 sizeMap 映射成 btn-lg / btn-md / btn-sm,未知值会拼出 undefined 类名(frameworks/Button.vue3.vue:34,39)"
|
||
},
|
||
{
|
||
"name": "text",
|
||
"type": "属性",
|
||
"desc": "默认插槽的兜底文案:<slot>{{ text }}</slot>,插槽有内容时 prop 不再渲染(frameworks/Button.vue3.vue:16)"
|
||
},
|
||
{
|
||
"name": "type",
|
||
"type": "String",
|
||
"desc": "类型(契约:类型:主按钮、次按钮、文字按钮、链接按钮、危险按钮)(frameworks/Button.vue3.vue:24)"
|
||
},
|
||
{
|
||
"name": "click",
|
||
"type": "(val: any) => void",
|
||
"desc": "点击时触发(frameworks/Button.vue3.vue:5)"
|
||
},
|
||
{
|
||
"name": "default",
|
||
"type": "插槽",
|
||
"desc": "默认插槽(组件文本或主体内容)(frameworks/Button.vue3.vue:24)"
|
||
}
|
||
]
|
||
},
|
||
"resources": [
|
||
{
|
||
"file": "frameworks/Button.vue3.vue",
|
||
"kind": "Vue 3",
|
||
"desc": "该端实现(本页 API 与用法的唯一权威来源)。"
|
||
},
|
||
{
|
||
"file": "frameworks/Button.css",
|
||
"kind": "样式",
|
||
"desc": "该组件的样式文件,类名口径以它为准。"
|
||
}
|
||
],
|
||
"exampleIds": [
|
||
"button-ex-1",
|
||
"button-ex-2",
|
||
"button-ex-3",
|
||
"button-ex-4",
|
||
"button-ex-5"
|
||
],
|
||
"notes": [
|
||
"props 声明见 frameworks/Button.vue3.vue:23-29,恰好 6 个;emits 见 frameworks/Button.vue3.vue:32。",
|
||
"size 到类名的映射表见 frameworks/Button.vue3.vue:34,类名拼装见 36-44。",
|
||
"禁用与加载状态下拦掉点击见 frameworks/Button.vue3.vue:46-49。",
|
||
"默认插槽与 text 兜底见 frameworks/Button.vue3.vue:16;icon 作为 path 的 d 使用见第 14 行。",
|
||
"该端样式写在组件内 <style scoped> 并用字面色值(frameworks/Button.vue3.vue:54-86),未引用 --kole-* 令牌;resources 里另列的 Button.css 与这份内联样式是两个口径。",
|
||
"disabled 的两处消费(根节点原生属性、onClick 开头 return)见 frameworks/Button.vue3.vue:4 与 47;size 只在 computed classes 里使用(第 39 行),模板没有独立尺寸分支。"
|
||
]
|
||
}
|