x-next 1.12.0 → 1.14.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.
- package/AI_CODING.md +6 -5
- package/AI_USAGE/catalog.md +106 -105
- package/AI_USAGE/components/alert-api.md +48 -0
- package/AI_USAGE/components/alert.md +222 -3
- package/AI_USAGE/components/bar-chart-api.md +177 -0
- package/AI_USAGE/components/bar-chart.md +297 -3
- package/AI_USAGE/components/boxicons.md +147 -0
- package/AI_USAGE/components/button-api.md +144 -0
- package/AI_USAGE/components/button.md +447 -3
- package/AI_USAGE/components/charts.md +81 -0
- package/AI_USAGE/components/checkbox-api.md +145 -0
- package/AI_USAGE/components/checkbox.md +365 -3
- package/AI_USAGE/components/color-picker-api.md +52 -0
- package/AI_USAGE/components/color-picker.md +211 -3
- package/AI_USAGE/components/config-provider-api.md +38 -0
- package/AI_USAGE/components/config-provider.md +250 -3
- package/AI_USAGE/components/date-picker-api.md +1114 -0
- package/AI_USAGE/components/date-picker.md +378 -3
- package/AI_USAGE/components/dialog-api.md +142 -0
- package/AI_USAGE/components/dialog.md +284 -3
- package/AI_USAGE/components/draggable-api.md +146 -0
- package/AI_USAGE/components/draggable.md +259 -0
- package/AI_USAGE/components/drawer-api.md +78 -0
- package/AI_USAGE/components/drawer.md +227 -0
- package/AI_USAGE/components/dropdown-api.md +529 -0
- package/AI_USAGE/components/dropdown.md +392 -3
- package/AI_USAGE/components/empty-api.md +36 -0
- package/AI_USAGE/components/empty.md +227 -3
- package/AI_USAGE/components/finicon.md +88 -0
- package/AI_USAGE/components/form-api.md +524 -0
- package/AI_USAGE/components/form.md +454 -0
- package/AI_USAGE/components/grid-api.md +527 -0
- package/AI_USAGE/components/grid.md +224 -0
- package/AI_USAGE/components/heatmap-api.md +122 -0
- package/AI_USAGE/components/heatmap.md +220 -0
- package/AI_USAGE/components/icon-api.md +4707 -0
- package/AI_USAGE/components/icon.md +257 -0
- package/AI_USAGE/components/image-api.md +440 -0
- package/AI_USAGE/components/image.md +465 -0
- package/AI_USAGE/components/input-api.md +184 -0
- package/AI_USAGE/components/input-number-api.md +66 -0
- package/AI_USAGE/components/input-number.md +294 -0
- package/AI_USAGE/components/input-tag-api.md +114 -0
- package/AI_USAGE/components/input-tag.md +482 -0
- package/AI_USAGE/components/input.md +293 -3
- package/AI_USAGE/components/layout-api.md +147 -0
- package/AI_USAGE/components/layout.md +230 -0
- package/AI_USAGE/components/line-chart-api.md +197 -0
- package/AI_USAGE/components/line-chart.md +279 -3
- package/AI_USAGE/components/link-api.md +42 -0
- package/AI_USAGE/components/link.md +197 -0
- package/AI_USAGE/components/menu-api.md +516 -0
- package/AI_USAGE/components/menu.md +268 -0
- package/AI_USAGE/components/message-api.md +215 -0
- package/AI_USAGE/components/message-box-api.md +108 -0
- package/AI_USAGE/components/message-box.md +268 -3
- package/AI_USAGE/components/message.md +231 -3
- package/AI_USAGE/components/network-api.md +91 -0
- package/AI_USAGE/components/network.md +378 -0
- package/AI_USAGE/components/notification-api.md +236 -0
- package/AI_USAGE/components/notification.md +275 -3
- package/AI_USAGE/components/pagination-api.md +62 -0
- package/AI_USAGE/components/pagination.md +386 -5
- package/AI_USAGE/components/pie-chart-api.md +109 -0
- package/AI_USAGE/components/pie-chart.md +245 -3
- package/AI_USAGE/components/popconfirm-api.md +75 -0
- package/AI_USAGE/components/popconfirm.md +231 -3
- package/AI_USAGE/components/popover-api.md +75 -0
- package/AI_USAGE/components/popover.md +208 -3
- package/AI_USAGE/components/popup-api.md +75 -0
- package/AI_USAGE/components/popup.md +52 -0
- package/AI_USAGE/components/progress-api.md +44 -0
- package/AI_USAGE/components/progress.md +248 -3
- package/AI_USAGE/components/radio-api.md +165 -0
- package/AI_USAGE/components/radio.md +259 -3
- package/AI_USAGE/components/rate-api.md +54 -0
- package/AI_USAGE/components/rate.md +233 -3
- package/AI_USAGE/components/resize-box-api.md +56 -0
- package/AI_USAGE/components/resize-box.md +231 -0
- package/AI_USAGE/components/scrollbar-api.md +77 -0
- package/AI_USAGE/components/scrollbar.md +218 -0
- package/AI_USAGE/components/select-api.md +758 -0
- package/AI_USAGE/components/select.md +640 -3
- package/AI_USAGE/components/skeleton-api.md +85 -0
- package/AI_USAGE/components/skeleton.md +150 -0
- package/AI_USAGE/components/slider-api.md +51 -0
- package/AI_USAGE/components/slider.md +233 -3
- package/AI_USAGE/components/space-api.md +38 -0
- package/AI_USAGE/components/space.md +145 -0
- package/AI_USAGE/components/spin-api.md +43 -0
- package/AI_USAGE/components/spin.md +205 -0
- package/AI_USAGE/components/steps-api.md +111 -0
- package/AI_USAGE/components/steps.md +201 -3
- package/AI_USAGE/components/switch-api.md +58 -0
- package/AI_USAGE/components/switch.md +290 -3
- package/AI_USAGE/components/table-api.md +2919 -0
- package/AI_USAGE/components/table.md +1414 -0
- package/AI_USAGE/components/tabs-api.md +135 -0
- package/AI_USAGE/components/tabs.md +308 -3
- package/AI_USAGE/components/tag-api.md +124 -0
- package/AI_USAGE/components/tag.md +292 -0
- package/AI_USAGE/components/textarea-api.md +55 -0
- package/AI_USAGE/components/textarea.md +326 -3
- package/AI_USAGE/components/time-picker-api.md +137 -0
- package/AI_USAGE/components/time-picker.md +271 -3
- package/AI_USAGE/components/time-range-selector-api.md +44 -0
- package/AI_USAGE/components/time-range-selector.md +355 -0
- package/AI_USAGE/components/timeline-api.md +93 -0
- package/AI_USAGE/components/timeline.md +312 -0
- package/AI_USAGE/components/tooltip-api.md +77 -0
- package/AI_USAGE/components/tooltip.md +182 -0
- package/AI_USAGE/components/trend-chart-api.md +119 -0
- package/AI_USAGE/components/trend-chart.md +335 -0
- package/AI_USAGE/components/trigger-api.md +124 -0
- package/AI_USAGE/components/trigger.md +185 -0
- package/AI_USAGE/components/upload-api.md +200 -0
- package/AI_USAGE/components/upload.md +711 -3
- package/AI_USAGE/components/watermark-api.md +87 -0
- package/AI_USAGE/components/watermark.md +200 -0
- package/AI_USAGE/core.md +1 -1
- package/AI_USAGE/index.md +35 -7
- package/AI_USAGE/recipes/form-on-demand.md +1 -1
- package/AI_USAGE.md +33657 -7
- package/CHANGELOG.md +40 -0
- package/dist/_utils/inherit-component-type.d.ts +11 -0
- package/dist/components/date-picker/index.d.ts +420 -5
- package/dist/components/form-input/index.d.ts +617 -2
- package/dist/components/layout/index.d.ts +689 -1
- package/dist/components/menu/index.d.ts +786 -1
- package/dist/components/network/Network.vue.d.ts +7 -3
- package/dist/components/network/index.d.ts +10 -2
- package/dist/components/network/props.d.ts +5 -0
- package/dist/components/network/utils.d.ts +3 -3
- package/dist/components/pagination/page-item-ellipsis.vue.d.ts +4 -1
- package/dist/components/pagination/page-item-step.vue.d.ts +101 -130
- package/dist/components/pagination/page-item.vue.d.ts +1 -0
- package/dist/components/pagination/page-jumper.vue.d.ts +1 -1
- package/dist/components/pagination/page-options.vue.d.ts +6 -4
- package/dist/components/pagination/utils.d.ts +3 -0
- package/dist/components/time-range-selector/index.d.ts +6 -6
- package/dist/es/_container/resize-observer-v2.js +1 -1
- package/dist/es/_container/resize-observer.js +1 -1
- package/dist/es/_hooks/use-resize-observer.js +1 -1
- package/dist/es/_styles/palette-aliases.js +4 -4
- package/dist/es/_utils/inherit-component-type.js +6 -0
- package/dist/es/_virtual/advancedFormat.js +1 -1
- package/dist/es/_virtual/customParseFormat.js +1 -1
- package/dist/es/_virtual/dayjs.min.js +1 -1
- package/dist/es/_virtual/isBetween.js +1 -1
- package/dist/es/_virtual/quarterOfYear.js +1 -1
- package/dist/es/_virtual/weekOfYear.js +1 -1
- package/dist/es/_virtual/weekYear.js +1 -1
- package/dist/es/_virtual/zh-cn.js +1 -1
- package/dist/es/components/button/Button.js +53 -42
- package/dist/es/components/date-picker/index.js +18 -17
- package/dist/es/components/draggable/useDraggable.js +1 -1
- package/dist/es/components/form/Form.vue2.js +1 -1
- package/dist/es/components/form/FormItem.vue2.js +1 -1
- package/dist/es/components/form-input/index.js +12 -11
- package/dist/es/components/form-input-number/InputNumber.js +1 -1
- package/dist/es/components/form-slider/Slider.vue2.js +1 -1
- package/dist/es/components/form-slider/slider-ticks.vue2.js +1 -1
- package/dist/es/components/form-slider/utils.js +1 -1
- package/dist/es/components/layout/index.js +10 -9
- package/dist/es/components/menu/MenuItem.js +1 -1
- package/dist/es/components/menu/hooks/use-level.js +5 -5
- package/dist/es/components/menu/index.js +13 -10
- package/dist/es/components/menu/overflow-wrap.js +1 -1
- package/dist/es/components/network/Network.vue.js +17 -12
- package/dist/es/components/network/Network.vue2.js +78 -70
- package/dist/es/components/network/utils.js +112 -71
- package/dist/es/components/pagination/Pagination.js +132 -123
- package/dist/es/components/pagination/page-item-ellipsis.vue.js +10 -10
- package/dist/es/components/pagination/page-item-ellipsis.vue2.js +24 -19
- package/dist/es/components/pagination/page-item-step.vue.js +14 -11
- package/dist/es/components/pagination/page-item-step.vue2.js +20 -22
- package/dist/es/components/pagination/page-item.vue.js +10 -9
- package/dist/es/components/pagination/page-item.vue2.js +24 -19
- package/dist/es/components/pagination/page-jumper.vue2.js +23 -23
- package/dist/es/components/pagination/page-options.vue.js +15 -10
- package/dist/es/components/pagination/page-options.vue2.js +21 -17
- package/dist/es/components/pagination/utils.js +4 -2
- package/dist/es/components/progress/circle.vue2.js +1 -1
- package/dist/es/components/progress/line.vue2.js +1 -1
- package/dist/es/components/progress/steps.vue2.js +1 -1
- package/dist/es/components/rate/Rate.js +1 -1
- package/dist/es/components/virtual-list-v2/virtual-list-item.js +1 -1
- package/dist/es/locale/en-US.js +2 -0
- package/dist/es/locale/zh-CN.js +2 -0
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/dayjs.min.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/locale/zh-cn.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/advancedFormat.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/customParseFormat.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/isBetween.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/quarterOfYear.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/weekOfYear.js +1 -1
- package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/dayjs@1.11.21/node_modules/dayjs/plugin/weekYear.js +1 -1
- package/dist/es/style.css +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.umd.js +3 -3
- package/dist/locale/interface.d.ts +3 -0
- package/dist/style/base.css +1 -1
- package/dist/style/button.css +1 -1
- package/dist/style/form-select.css +1 -1
- package/dist/style/network.css +1 -1
- package/dist/style/pagination.css +1 -1
- package/dist/style/table.css +1 -1
- package/dist/style.css +1 -1
- package/package.json +10 -5
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/index.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/is.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/locale/en-US.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/array.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/base.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/boolean.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/custom.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/number.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/object.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/string.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/rules/type.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/b-validate@1.5.3/node_modules/b-validate/es/util.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/compute-scroll-into-view@3.1.1/node_modules/compute-scroll-into-view/dist/index.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/number-precision@1.6.0/node_modules/number-precision/build/index.es.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/resize-observer-polyfill@1.5.1/node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/scroll-into-view-if-needed@3.1.0/node_modules/scroll-into-view-if-needed/dist/index.js +0 -0
- /package/dist/es/{Users/xuyu/Code/x-next/node_modules → node_modules}/.pnpm/sortablejs@1.15.7/node_modules/sortablejs/modular/sortable.esm.js +0 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
<!-- Generated by pnpm generate:ai-usage. Edit script/ai-usage/content.md and script/ai-usage/. -->
|
|
2
|
+
# InputTag AI 使用
|
|
3
|
+
|
|
4
|
+
适用版本:x-next@1.14.0;来源指纹:`014984639d816a2c7e25eb22690c586b0b2e8efba6846bec8a4e424db41a09e9`。
|
|
5
|
+
|
|
6
|
+
先读 [通用接入](../core.md)。公开导出:`InputTag`;主要模型:v-model、v-model:input-value。完整 Props、Events、Slots、实例方法与服务签名见 [本地 API](./input-tag-api.md),包含本组件族全部子组件和别名。
|
|
7
|
+
|
|
8
|
+
按需样式:`x-next/style/form-input-tag`(包含 base.css、form-input-tag.css)。代码块未单独引样式时在应用入口加载全量样式,或按实际所有组件加载 JS 入口;不要仅因复制一个组件页就漏掉其中的 Button 等组合依赖。
|
|
9
|
+
|
|
10
|
+
## 场景用法
|
|
11
|
+
|
|
12
|
+
以下示例从本地 `src/docs/components/input-tag.md` 显式导入到独立 AI 源,补齐局部注册、状态和样式后进行严格模板检查。上方已核验行为优先;原始 prop 默认值、包装透传和示例业务适配分别查 [完整 API](./input-tag-api.md) 与场景说明。类型通过不代表所有散文和交互已验证。
|
|
13
|
+
|
|
14
|
+
### 用途与选型
|
|
15
|
+
|
|
16
|
+
用于录入多个短文本项,如标签、关键词、邮箱列表。
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### 何时使用
|
|
20
|
+
|
|
21
|
+
- 需要一次录入多个等价的短文本,例如关键词、收件人、分类名。
|
|
22
|
+
- 录入后希望以标签形式回显,并允许逐个删除。
|
|
23
|
+
- 需要限制展示数量、去重、前缀后缀或与 Form 校验联动时。
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### 基础用法
|
|
27
|
+
|
|
28
|
+
输入内容后按回车创建标签,点击标签上的关闭按钮删除,`allow-clear` 提供整组清空按钮。
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<script setup lang="ts">
|
|
32
|
+
import 'x-next/style.css';
|
|
33
|
+
import { InputTag } from 'x-next';
|
|
34
|
+
import { ref } from 'vue';
|
|
35
|
+
|
|
36
|
+
const tags = ref(['Vue', 'TypeScript']);
|
|
37
|
+
</script>
|
|
38
|
+
<template>
|
|
39
|
+
<InputTag v-model="tags" placeholder="输入后回车" allow-clear />
|
|
40
|
+
</template>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 状态
|
|
44
|
+
|
|
45
|
+
`disabled` 禁用输入与删除,`readonly` 保留展示但不可编辑,`error` 使用错误态边框与背景。切换状态后组件会立即响应。
|
|
46
|
+
|
|
47
|
+
```vue
|
|
48
|
+
<script setup lang="ts">
|
|
49
|
+
import 'x-next/style.css';
|
|
50
|
+
import { InputTag, Button } from 'x-next';
|
|
51
|
+
import { ref } from 'vue';
|
|
52
|
+
|
|
53
|
+
const tags = ref(['Vue', 'TypeScript']);
|
|
54
|
+
const state = ref<'normal' | 'disabled' | 'readonly' | 'error'>('normal');
|
|
55
|
+
</script>
|
|
56
|
+
<template>
|
|
57
|
+
<InputTag
|
|
58
|
+
v-model="tags"
|
|
59
|
+
:disabled="state === 'disabled'"
|
|
60
|
+
:readonly="state === 'readonly'"
|
|
61
|
+
:error="state === 'error'"
|
|
62
|
+
placeholder="输入后回车"
|
|
63
|
+
allow-clear
|
|
64
|
+
/>
|
|
65
|
+
<Button size="small" @click="state = 'disabled'">禁用</Button>
|
|
66
|
+
<Button size="small" @click="state = 'readonly'">只读</Button>
|
|
67
|
+
<Button size="small" @click="state = 'error'">错误</Button>
|
|
68
|
+
</template>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 尺寸与高度
|
|
72
|
+
|
|
73
|
+
同一尺寸下,空态、单个标签、多个标签的外框高度保持一致;标签内容过长时标签自身换行增高。
|
|
74
|
+
|
|
75
|
+
```vue
|
|
76
|
+
<script setup lang="ts">
|
|
77
|
+
import 'x-next/style.css';
|
|
78
|
+
import { InputTag } from 'x-next';
|
|
79
|
+
import { ref } from 'vue';
|
|
80
|
+
|
|
81
|
+
const emptyTags = ref<string[]>([]);
|
|
82
|
+
const singleTags = ref(['Vue']);
|
|
83
|
+
</script>
|
|
84
|
+
<template>
|
|
85
|
+
<InputTag v-model="emptyTags" size="mini" placeholder="空态" />
|
|
86
|
+
<InputTag v-model="singleTags" size="mini" />
|
|
87
|
+
<InputTag v-model="emptyTags" size="small" placeholder="空态" />
|
|
88
|
+
<InputTag v-model="singleTags" size="small" />
|
|
89
|
+
<InputTag v-model="emptyTags" size="medium" placeholder="空态" />
|
|
90
|
+
<InputTag v-model="singleTags" size="medium" />
|
|
91
|
+
<InputTag v-model="emptyTags" size="large" placeholder="空态" />
|
|
92
|
+
<InputTag v-model="singleTags" size="large" />
|
|
93
|
+
</template>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 限制展示数量
|
|
97
|
+
|
|
98
|
+
`maxTagCount` 只限制展示数量,多出的标签折叠为 `+N...`,不限制可创建数量,也不阻止删除。
|
|
99
|
+
|
|
100
|
+
```vue
|
|
101
|
+
<script setup lang="ts">
|
|
102
|
+
import 'x-next/style.css';
|
|
103
|
+
import { InputTag } from 'x-next';
|
|
104
|
+
import { ref } from 'vue';
|
|
105
|
+
|
|
106
|
+
const tags = ref(['one', 'two', 'three', 'four']);
|
|
107
|
+
</script>
|
|
108
|
+
<template>
|
|
109
|
+
<InputTag v-model="tags" :max-tag-count="2" allow-clear />
|
|
110
|
+
</template>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 前缀和后缀
|
|
114
|
+
|
|
115
|
+
`prefix` 用于输入框内部的前置装饰,`suffix` 用于后置内容;已有内置清空按钮时两者会共同占用右侧空间。
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<script setup lang="ts">
|
|
119
|
+
import 'x-next/style.css';
|
|
120
|
+
import { InputTag } from 'x-next';
|
|
121
|
+
import { ref } from 'vue';
|
|
122
|
+
|
|
123
|
+
const tags = ref(['Vue', 'TypeScript']);
|
|
124
|
+
</script>
|
|
125
|
+
<template>
|
|
126
|
+
<InputTag v-model="tags" allow-clear>
|
|
127
|
+
<template #prefix>标签</template>
|
|
128
|
+
<template #suffix>{{ tags.length }}</template>
|
|
129
|
+
</InputTag>
|
|
130
|
+
</template>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 唯一值
|
|
134
|
+
|
|
135
|
+
`uniqueValue` 阻止创建已存在的标签,比较基于归一化后的 `value`,字符串与数字严格区分(`1` 与 `'1'` 视为不同)。被阻止时仍会触发 `press-enter`,输入内容保留。
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<script setup lang="ts">
|
|
139
|
+
import 'x-next/style.css';
|
|
140
|
+
import { InputTag } from 'x-next';
|
|
141
|
+
import { ref } from 'vue';
|
|
142
|
+
import type { TagData } from 'x-next';
|
|
143
|
+
|
|
144
|
+
const tags = ref<Array<string | number | TagData>>(['Vue', 1, { value: 'id-a', label: '对象 A' }]);
|
|
145
|
+
</script>
|
|
146
|
+
<template>
|
|
147
|
+
<InputTag v-model="tags" unique-value placeholder="重复值不会再次创建" />
|
|
148
|
+
</template>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 受控输入值
|
|
152
|
+
|
|
153
|
+
`v-model` 控制标签数组,`v-model:input-value` 控制输入框中的未提交草稿。草稿受控时,组件的输入只上报变更,由使用方决定是否回写。
|
|
154
|
+
|
|
155
|
+
```vue
|
|
156
|
+
<script setup lang="ts">
|
|
157
|
+
import 'x-next/style.css';
|
|
158
|
+
import { InputTag, Button } from 'x-next';
|
|
159
|
+
import { ref } from 'vue';
|
|
160
|
+
|
|
161
|
+
const tags = ref(['Vue']);
|
|
162
|
+
const draft = ref('草稿');
|
|
163
|
+
const reset = () => {
|
|
164
|
+
tags.value = ['Vue'];
|
|
165
|
+
draft.value = '草稿';
|
|
166
|
+
};
|
|
167
|
+
</script>
|
|
168
|
+
<template>
|
|
169
|
+
<InputTag v-model="tags" v-model:input-value="draft" placeholder="输入后回车" allow-clear />
|
|
170
|
+
<p role="status">标签:{{ tags.join('、') || '无' }};草稿:{{ draft || '空' }}</p>
|
|
171
|
+
<Button size="small" @click="reset">重置为初始值</Button>
|
|
172
|
+
</template>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 保留输入内容
|
|
176
|
+
|
|
177
|
+
`retainInputValue` 默认 `false`,即创建标签后和失焦时都会清空草稿。传 `true` 两者都保留,也可用对象分别控制 `create` 与 `blur`。
|
|
178
|
+
|
|
179
|
+
```vue
|
|
180
|
+
<script setup lang="ts">
|
|
181
|
+
import 'x-next/style.css';
|
|
182
|
+
import { InputTag } from 'x-next';
|
|
183
|
+
import { ref } from 'vue';
|
|
184
|
+
|
|
185
|
+
const tags = ref(['draft']);
|
|
186
|
+
const draft = ref('');
|
|
187
|
+
const blurDraft = ref('');
|
|
188
|
+
const createDraft = ref('');
|
|
189
|
+
</script>
|
|
190
|
+
<template>
|
|
191
|
+
<InputTag v-model="tags" v-model:input-value="draft" retain-input-value />
|
|
192
|
+
<InputTag
|
|
193
|
+
v-model="tags"
|
|
194
|
+
v-model:input-value="blurDraft"
|
|
195
|
+
:retain-input-value="{ create: false, blur: true }"
|
|
196
|
+
/>
|
|
197
|
+
<InputTag
|
|
198
|
+
v-model="tags"
|
|
199
|
+
v-model:input-value="createDraft"
|
|
200
|
+
:retain-input-value="{ create: true, blur: false }"
|
|
201
|
+
/>
|
|
202
|
+
</template>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 对象标签
|
|
206
|
+
|
|
207
|
+
对象标签用 `fieldNames` 映射 `value`、`label`、`closable`、`tagProps` 四个字段。`label` 缺失时回退为 `String(value)`;缺少有效 `value` 的对象会被忽略。
|
|
208
|
+
|
|
209
|
+
```vue
|
|
210
|
+
<script setup lang="ts">
|
|
211
|
+
import 'x-next/style.css';
|
|
212
|
+
import { InputTag } from 'x-next';
|
|
213
|
+
import { ref } from 'vue';
|
|
214
|
+
import type { InputTagFieldNames, TagData } from 'x-next';
|
|
215
|
+
|
|
216
|
+
const tags = ref<Array<string | number | TagData>>([
|
|
217
|
+
{ id: 'a', name: '设计', canRemove: false },
|
|
218
|
+
{ id: 'b', name: '研发', canRemove: true },
|
|
219
|
+
]);
|
|
220
|
+
const fieldNames: InputTagFieldNames = {
|
|
221
|
+
value: 'id',
|
|
222
|
+
label: 'name',
|
|
223
|
+
closable: 'canRemove',
|
|
224
|
+
};
|
|
225
|
+
// Enter 新建的字符串标签只有 value,需要回退取值
|
|
226
|
+
const formatTag = (data: TagData) => `#${data.name ?? data.label ?? data.value}`;
|
|
227
|
+
</script>
|
|
228
|
+
<template>
|
|
229
|
+
<InputTag v-model="tags" :field-names="fieldNames" :format-tag="formatTag" allow-clear />
|
|
230
|
+
</template>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 自定义标签
|
|
234
|
+
|
|
235
|
+
`tag` 插槽接收归一化后的 `data`,可自定义标签渲染;对象标签与新建字符串标签混用时同样需要回退取值。
|
|
236
|
+
|
|
237
|
+
```vue
|
|
238
|
+
<script setup lang="ts">
|
|
239
|
+
import 'x-next/style.css';
|
|
240
|
+
import { InputTag } from 'x-next';
|
|
241
|
+
import { ref } from 'vue';
|
|
242
|
+
import type { InputTagFieldNames, TagData } from 'x-next';
|
|
243
|
+
|
|
244
|
+
const tags = ref<Array<string | number | TagData>>([{ id: 'a', name: '设计' }]);
|
|
245
|
+
const fieldNames: InputTagFieldNames = { value: 'id', label: 'name' };
|
|
246
|
+
</script>
|
|
247
|
+
<template>
|
|
248
|
+
<InputTag v-model="tags" :field-names="fieldNames">
|
|
249
|
+
<template #tag="{ data }">
|
|
250
|
+
{{ data.name ?? data.label ?? data.value }}
|
|
251
|
+
</template>
|
|
252
|
+
</InputTag>
|
|
253
|
+
</template>
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 标签不换行
|
|
257
|
+
|
|
258
|
+
`tagNowrap` 让单个标签的内容不换行,标签列表本身仍可换行。
|
|
259
|
+
|
|
260
|
+
```vue
|
|
261
|
+
<script setup lang="ts">
|
|
262
|
+
import 'x-next/style.css';
|
|
263
|
+
import { InputTag } from 'x-next';
|
|
264
|
+
import { ref } from 'vue';
|
|
265
|
+
|
|
266
|
+
const tags = ref(['这是一段很长很长的标签内容,用于检查不换行时的显示效果']);
|
|
267
|
+
</script>
|
|
268
|
+
<template>
|
|
269
|
+
<InputTag v-model="tags" tag-nowrap />
|
|
270
|
+
</template>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### 标签样式
|
|
274
|
+
|
|
275
|
+
`tagProps` 透传给内部 Tag,可设置内置颜色、自定义颜色与边框。删除权限只收紧不放开:顶层 `closable: false` 时 `tagProps.closable: true` 无效;顶层可关闭时 `tagProps.closable: false` 会隐藏关闭按钮并让键盘删除跳过该项。
|
|
276
|
+
|
|
277
|
+
```vue
|
|
278
|
+
<script setup lang="ts">
|
|
279
|
+
import 'x-next/style.css';
|
|
280
|
+
import { InputTag } from 'x-next';
|
|
281
|
+
import { ref } from 'vue';
|
|
282
|
+
import type { TagData } from 'x-next';
|
|
283
|
+
|
|
284
|
+
const tags = ref<Array<string | number | TagData>>([
|
|
285
|
+
{ value: 'blue', label: '内置蓝色', tagProps: { color: 'blue', bordered: true } },
|
|
286
|
+
{ value: 'custom', label: '自定义颜色', tagProps: { color: '#7c3aed' } },
|
|
287
|
+
{ value: 'narrow', label: 'tagProps 禁止删除', closable: true, tagProps: { color: 'green', closable: false } },
|
|
288
|
+
{ value: 'locked', label: '顶层禁止删除', closable: false, tagProps: { color: 'red', closable: true } },
|
|
289
|
+
]);
|
|
290
|
+
</script>
|
|
291
|
+
<template>
|
|
292
|
+
<InputTag v-model="tags" allow-clear />
|
|
293
|
+
</template>
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 事件回调
|
|
297
|
+
|
|
298
|
+
创建标签依次触发 `change`、`press-enter` 和清空草稿的 `input-value-change`,因此示例用日志列表保留完整顺序。
|
|
299
|
+
|
|
300
|
+
```vue
|
|
301
|
+
<script setup lang="ts">
|
|
302
|
+
import 'x-next/style.css';
|
|
303
|
+
import { InputTag } from 'x-next';
|
|
304
|
+
import { ref } from 'vue';
|
|
305
|
+
import type { TagData } from 'x-next';
|
|
306
|
+
|
|
307
|
+
const tags = ref(['日志']);
|
|
308
|
+
const logs = ref<string[]>([]);
|
|
309
|
+
let sequence = 0;
|
|
310
|
+
const append = (message: string) => {
|
|
311
|
+
logs.value = [...logs.value, `${++sequence}. ${message}`].slice(-12);
|
|
312
|
+
};
|
|
313
|
+
const handleChange = (value: Array<string | number | TagData>, event: Event) => {
|
|
314
|
+
append(`change (${event.type}):${value.length} 个标签`);
|
|
315
|
+
};
|
|
316
|
+
const handleInputValueChange = (value: string, event: Event) => {
|
|
317
|
+
append(`input-value-change (${event.type}):${value || '空'}`);
|
|
318
|
+
};
|
|
319
|
+
const handlePressEnter = (value: string, event: KeyboardEvent) => {
|
|
320
|
+
append(`press-enter (${event.type}):${value}`);
|
|
321
|
+
};
|
|
322
|
+
const handleRemove = (value: string | number, event: Event) => {
|
|
323
|
+
append(`remove (${event.type}):${value}`);
|
|
324
|
+
};
|
|
325
|
+
const handleClear = (event: MouseEvent) => {
|
|
326
|
+
append(`clear (${event.type})`);
|
|
327
|
+
};
|
|
328
|
+
</script>
|
|
329
|
+
<template>
|
|
330
|
+
<InputTag
|
|
331
|
+
v-model="tags"
|
|
332
|
+
allow-clear
|
|
333
|
+
@change="handleChange"
|
|
334
|
+
@input-value-change="handleInputValueChange"
|
|
335
|
+
@press-enter="handlePressEnter"
|
|
336
|
+
@remove="handleRemove"
|
|
337
|
+
@clear="handleClear"
|
|
338
|
+
/>
|
|
339
|
+
<div role="status">
|
|
340
|
+
<div v-for="log in logs" :key="log">{{ log }}</div>
|
|
341
|
+
</div>
|
|
342
|
+
</template>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 方法
|
|
346
|
+
|
|
347
|
+
`focus`、`blur` 通过组件实例调用。
|
|
348
|
+
|
|
349
|
+
```vue
|
|
350
|
+
<script setup lang="ts">
|
|
351
|
+
import 'x-next/style.css';
|
|
352
|
+
import { InputTag, Button } from 'x-next';
|
|
353
|
+
import { ref } from 'vue';
|
|
354
|
+
import type { InputTagInstance } from 'x-next';
|
|
355
|
+
|
|
356
|
+
const tags = ref(['Vue', 'TypeScript']);
|
|
357
|
+
const inputTagRef = ref<InputTagInstance>();
|
|
358
|
+
</script>
|
|
359
|
+
<template>
|
|
360
|
+
<InputTag ref="inputTagRef" v-model="tags" />
|
|
361
|
+
<Button @click="inputTagRef?.focus()">聚焦</Button>
|
|
362
|
+
<Button @click="inputTagRef?.blur()">失焦</Button>
|
|
363
|
+
</template>
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 原生属性
|
|
367
|
+
|
|
368
|
+
`id`、`name`、`maxlength`、`aria-*` 等原生属性会落到内部 input,而不是外层容器;表单类事件(`input`、`keydown` 等)同样绑定在原生 input 上。
|
|
369
|
+
|
|
370
|
+
```vue
|
|
371
|
+
<script setup lang="ts">
|
|
372
|
+
import 'x-next/style.css';
|
|
373
|
+
import { InputTag } from 'x-next';
|
|
374
|
+
import { ref } from 'vue';
|
|
375
|
+
|
|
376
|
+
const tags = ref(['Vue']);
|
|
377
|
+
const draft = ref('');
|
|
378
|
+
import type { InputHTMLAttributes } from 'vue';
|
|
379
|
+
const nativeAttrs1 = { "id": "input-tag-native", "name": "keywords", "maxlength": "12", "aria-label": "关键词标签输入" } satisfies InputHTMLAttributes;
|
|
380
|
+
</script>
|
|
381
|
+
<template>
|
|
382
|
+
<InputTag :input-attrs="nativeAttrs1"
|
|
383
|
+
v-model="tags"
|
|
384
|
+
v-model:input-value="draft"
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
/>
|
|
390
|
+
</template>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### 在 Form 中校验
|
|
394
|
+
|
|
395
|
+
组件放进 `x-form-item` 后会自动继承 Form 的尺寸与禁用状态,并按 FormItem 的校验规则展示错误。默认 `validateTrigger` 为 `change`,即值变化时触发校验。
|
|
396
|
+
|
|
397
|
+
```vue
|
|
398
|
+
<script setup lang="ts">
|
|
399
|
+
import 'x-next/style.css';
|
|
400
|
+
import { Form, FormItem, InputTag, Space, Button } from 'x-next';
|
|
401
|
+
const tags = ref(['Vue', 'TypeScript']);
|
|
402
|
+
|
|
403
|
+
import { reactive, ref } from 'vue';
|
|
404
|
+
import type { FormInstance, FieldRule } from 'x-next';
|
|
405
|
+
|
|
406
|
+
const formState = reactive({ tags: [] as string[] });
|
|
407
|
+
const formRules: Record<string, FieldRule[]> = {
|
|
408
|
+
tags: [{ type: 'array', required: true, message: '至少添加一个标签' }],
|
|
409
|
+
};
|
|
410
|
+
const formRef = ref<FormInstance>();
|
|
411
|
+
const validateResult = ref('');
|
|
412
|
+
|
|
413
|
+
const handleValidate = async () => {
|
|
414
|
+
const errors = await formRef.value!.validate();
|
|
415
|
+
validateResult.value = errors
|
|
416
|
+
? `校验失败:${Object.values(errors).map((error) => error.message).join(';')}`
|
|
417
|
+
: '校验通过';
|
|
418
|
+
};
|
|
419
|
+
const handleReset = () => {
|
|
420
|
+
formRef.value!.resetFields();
|
|
421
|
+
validateResult.value = '已重置';
|
|
422
|
+
};
|
|
423
|
+
</script>
|
|
424
|
+
<template>
|
|
425
|
+
<Form ref="formRef" :model="formState" :rules="formRules">
|
|
426
|
+
<FormItem field="tags" label="标签">
|
|
427
|
+
<InputTag v-model="formState.tags" placeholder="请输入标签后回车" />
|
|
428
|
+
</FormItem>
|
|
429
|
+
<FormItem>
|
|
430
|
+
<Space>
|
|
431
|
+
<Button type="primary" @click="handleValidate">校验</Button>
|
|
432
|
+
<Button @click="handleReset">重置</Button>
|
|
433
|
+
</Space>
|
|
434
|
+
</FormItem>
|
|
435
|
+
</Form>
|
|
436
|
+
<p role="status">{{ validateResult }}</p>
|
|
437
|
+
</template>
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### 已知交互说明
|
|
441
|
+
|
|
442
|
+
- 输入为空时按 Backspace 删除最后一个**可关闭**标签;末尾标签不可关闭时继续向前查找。
|
|
443
|
+
- 输入内容为空时按 Enter 不创建标签,也不触发 `press-enter`。
|
|
444
|
+
- `uniqueValue` 比较归一化后的 `value`,基于严格相等,数字 `1` 与字符串 `'1'` 视为不同值。
|
|
445
|
+
- `maxTagCount` 只影响展示,折叠出的 `+N...` 不可关闭;Backspace 删除的是最后一个真实可关闭标签。
|
|
446
|
+
- 对象标签缺少 `value`(或 `fieldNames.value` 字段)时会被忽略,不会渲染,删除时也会跳过。
|
|
447
|
+
- 标签删除权限只收紧不放开:顶层 `closable` 是总开关,`tagProps.closable: false` 可在其基础上禁用删除。
|
|
448
|
+
- 关闭按钮的无障碍名称包含各标签文案(如“关闭标签 Vue”),便于屏幕阅读器区分。
|
|
449
|
+
- 用键盘激活关闭按钮或清空按钮后,焦点会回到输入框,便于继续输入。
|
|
450
|
+
- 直接使用 InputTag 时,输入法组合结束(`compositionend`)同样会触发 FormItem 的 `input` 校验,与普通输入一致。
|
|
451
|
+
- 同名事件回调:`inputAttrs` 与组件透传的 `attrs` 都提供同一事件(如 `onInput`)时,`inputAttrs` 优先;组件内部处理器仍会执行。
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
### TagData
|
|
455
|
+
|
|
456
|
+
| 字段 | 说明 | 类型 | 默认值 |
|
|
457
|
+
| --- | --- | --- | --- |
|
|
458
|
+
| `value` | 标签值,缺失时整项被忽略 | `string \| number` | `-` |
|
|
459
|
+
| `label` | 标签内容,缺失时回退为 `String(value)` | `string` | `-` |
|
|
460
|
+
| `closable` | 是否可删除 | `boolean` | `true` |
|
|
461
|
+
| `tagProps` | 透传给内部 Tag 的属性 | `TagProps` | `-` |
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
### fieldNames
|
|
465
|
+
|
|
466
|
+
| 字段 | 说明 | 默认值 |
|
|
467
|
+
| --- | --- | --- |
|
|
468
|
+
| `value` | 取值字段名 | `'value'` |
|
|
469
|
+
| `label` | 内容字段名 | `'label'` |
|
|
470
|
+
| `closable` | 删除开关字段名 | `'closable'` |
|
|
471
|
+
| `tagProps` | Tag 属性字段名 | `'tagProps'` |
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
### 关联能力
|
|
475
|
+
|
|
476
|
+
- 多选 Select 内部复用 InputTag 渲染标签,`maxTagCount`、`tagNowrap`、标签删除等行为一致。
|
|
477
|
+
- 需要校验、错误提示和布局时配合 `x-form` / `x-form-item` 使用。
|
|
478
|
+
- `InputTag`、`Input`、`Textarea` 同属输入组件族,尺寸与状态命名一致。
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
返回 [AI 索引](../index.md)。先查本页与 [本地 API](./input-tag-api.md);需要更深类型时查 [公开组件导航](../catalog.md),不默认上网查找本包用法。
|