vue2-components-plus 1.0.28 → 1.0.32

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.
@@ -0,0 +1,297 @@
1
+ # 自定义指令使用说明(`v-sline` / `v-length` / `v-permission` / `v-event-unuse` / `v-event-use`)
2
+
3
+ 本文档严格对应 `packages/directives/index.js` 的当前实现,重点是帮助 AI 生成“可运行、不过度脑补、行为符合源码”的 Vue2 页面代码。
4
+
5
+ ## 1. 入口与注册方式
6
+
7
+ 当前仓库的所有自定义指令都定义在同一个文件中:
8
+
9
+ | 入口 | 路径 |
10
+ |---|---|
11
+ | 指令注册函数 | `packages/directives/index.js` |
12
+ | 导出函数 | `registerDirective(Vue)` |
13
+
14
+ 推荐注册方式有两种。
15
+
16
+ ### 1.1 安装整库插件
17
+
18
+ ```js
19
+ import Vue from 'vue'
20
+ import Vue2ComponentsPlus from 'vue2-components-plus'
21
+
22
+ Vue.use(Vue2ComponentsPlus)
23
+ ```
24
+
25
+ ### 1.2 在源码环境中单独注册
26
+
27
+ ```js
28
+ import Vue from 'vue'
29
+ import { registerDirective } from '../../packages/directives'
30
+
31
+ registerDirective(Vue)
32
+ ```
33
+
34
+ ## 2. 指令总览
35
+
36
+ | 指令 | 作用 | 是否有修饰符 |
37
+ |---|---|---|
38
+ | `v-sline` | 单行省略 | 否 |
39
+ | `v-length` | 输入限制 | 是 |
40
+ | `v-permission` | 权限显示控制 | 是 |
41
+ | `v-event-unuse` | 禁用指针事件 | 否 |
42
+ | `v-event-use` | 恢复指针事件 | 否 |
43
+
44
+ ## 3. `v-sline`
45
+
46
+ ### 3.1 作用
47
+
48
+ 绑定后会直接给元素写入以下样式:
49
+
50
+ - `white-space: nowrap`
51
+ - `overflow: hidden`
52
+ - `text-overflow: ellipsis`
53
+ - `display: inline-block`
54
+ - `max-width: 100%`
55
+
56
+ ### 3.2 用法
57
+
58
+ ```vue
59
+ <span v-sline>{{ longText }}</span>
60
+ ```
61
+
62
+ ### 3.3 适用场景
63
+
64
+ - 表格单元格长文本
65
+ - 只读详情页文本
66
+ - 表单只读态字段展示
67
+
68
+ ## 4. `v-length`
69
+
70
+ `v-length` 是当前指令里最核心的一个。它会监听 `input`、`compositionstart`、`compositionend`,对中文输入法场景友好,不会在拼音组合输入过程中强行截断。
71
+
72
+ ### 4.1 绑定目标
73
+
74
+ - 可以直接绑在原生 `input` / `textarea`
75
+ - 也可以绑在组件根节点,内部会自动寻找 `input, textarea`
76
+ - 对 `Element UI` 的 `el-input` 可直接使用
77
+
78
+ ### 4.2 基础写法
79
+
80
+ ```vue
81
+ <el-input v-model="form.name" v-length="20" />
82
+ ```
83
+
84
+ 含义:最多 20 个字符。
85
+
86
+ ### 4.3 修饰符
87
+
88
+ | 修饰符 | 说明 |
89
+ |---|---|
90
+ | `.number` | 仅允许数字、首位负号、一个小数点 |
91
+ | `.regex` | 按正则逐字符校验 |
92
+ | `.range` | 数值范围约束,可配合 `int: true` 实现整数模式 |
93
+
94
+ ### 4.4 `binding.value` 配置结构
95
+
96
+ | 字段 | 类型 | 默认值 | 说明 |
97
+ |---|---|---|---|
98
+ | `maxLength` | `Number` | `50` | 最大长度 |
99
+ | `pattern` | `RegExp` | `null` | `.regex` 模式使用 |
100
+ | `min` | `Number` | `null` | `.range` 最小值 |
101
+ | `max` | `Number` | `null` | `.range` 最大值 |
102
+ | `int` | `Boolean` | `false` | `.range` 时是否仅允许整数 |
103
+
104
+ ### 4.5 典型写法
105
+
106
+ ```vue
107
+ <el-input v-model="form.mobile" v-length.number="11" />
108
+ <el-input v-model="form.code" v-length.regex="{ maxLength: 6, pattern: /^[A-Z0-9]*$/ }" />
109
+ <el-input v-model="form.score" v-length.range="{ min: 0, max: 100 }" />
110
+ <el-input v-model="form.age" v-length.range="{ min: 1, max: 120, int: true, maxLength: 3 }" />
111
+ ```
112
+
113
+ ### 4.6 当前实现的真实行为
114
+
115
+ - 值被修正后,会主动派发一次原生 `input` 事件,确保 `v-model` 同步
116
+ - `.number` 允许负号和小数点,不会自动限制为正整数
117
+ - `.range` 超出范围时会直接钳制到边界值
118
+ - `.range + int: true` 时只允许整数,是否允许负号取决于 `min < 0`
119
+ - `.regex` 是“逐字符累积校验”,`pattern` 必须允许中间态
120
+
121
+ ### 4.7 `.regex` 模式注意事项
122
+
123
+ 为了让 AI 生成稳定代码,必须遵守下面两点:
124
+
125
+ - 正则不要使用全局 `g` 修饰符
126
+ - 正则应允许中间输入状态,例如验证码可写成 `^[A-Z0-9]*$`,不要写必须一次成型的表达式
127
+
128
+ ## 5. `v-permission`
129
+
130
+ ### 5.1 权限来源
131
+
132
+ 权限列表读取顺序如下:
133
+
134
+ 1. `sessionStorage.getItem('btnsPermission')`
135
+ 2. `localStorage.getItem('btnsPermission')`
136
+ 3. 默认空数组
137
+
138
+ 权限数据要求是 JSON 数组,每个元素是字符串。
139
+
140
+ ```js
141
+ sessionStorage.setItem('btnsPermission', JSON.stringify(['add_btn', 'export_btn', 'admin-btn']))
142
+ ```
143
+
144
+ ### 5.2 匹配模式
145
+
146
+ | 写法 | 匹配依据 |
147
+ |---|---|
148
+ | `v-permission` | 按元素 `id` 匹配 |
149
+ | `v-permission.id` | 按元素 `id` 匹配 |
150
+ | `v-permission.class` | 按元素 `classList` 匹配 |
151
+
152
+ ### 5.3 无权限时的表现
153
+
154
+ | 写法 | 无权限效果 |
155
+ |---|---|
156
+ | `v-permission` / `v-permission.id` | `visibility: hidden` 且 `pointer-events: none` |
157
+ | `v-permission.display` / `v-permission.id.display` / `v-permission.class.display` | `display: none` |
158
+
159
+ ### 5.4 示例
160
+
161
+ ```vue
162
+ <el-button id="add_btn" v-permission type="primary">新增</el-button>
163
+ <el-button id="export_btn" v-permission.id.display>导出</el-button>
164
+ <el-button class="admin-btn" v-permission.class>管理员入口</el-button>
165
+ ```
166
+
167
+ ### 5.5 当前实现限制
168
+
169
+ - 权限只在 `inserted` 时检查一次,不会自动响应后续权限数据变化
170
+ - 如果权限列表改变,需要刷新页面或重新渲染元素
171
+ - 使用 `id` 模式时,元素必须真的写上稳定 `id`
172
+ - 使用 `class` 模式时,匹配逻辑是“权限值是否存在于当前元素 classList 中”
173
+
174
+ ## 6. `v-event-unuse` / `v-event-use`
175
+
176
+ ### 6.1 行为
177
+
178
+ | 指令 | 结果 |
179
+ |---|---|
180
+ | `v-event-unuse` | `pointer-events: none` |
181
+ | `v-event-use` | `pointer-events: auto` |
182
+
183
+ ### 6.2 典型组合
184
+
185
+ ```vue
186
+ <div v-event-unuse>
187
+ <div v-event-use @click="handleChildClick">子区域恢复交互</div>
188
+ </div>
189
+ ```
190
+
191
+ ### 6.3 适合场景
192
+
193
+ - 蒙层区域透传点击
194
+ - 父容器禁用交互、局部按钮恢复交互
195
+ - 自定义卡片覆盖层
196
+
197
+ ## 7. Demo 覆盖内容
198
+
199
+ `src/views/DirectivesDemo.vue` 建议覆盖以下几类能力,AI 生成页面时也应尽量完整体现:
200
+
201
+ | 模块 | 建议覆盖点 |
202
+ |---|---|
203
+ | 省略 | 固定宽度容器中的长文本 |
204
+ | 输入限制 | 普通限长、数字、正则、区间、整数区间 |
205
+ | 权限 | `id` 模式、`class` 模式、`display` 模式 |
206
+ | 事件穿透 | 父级禁用、子级恢复 |
207
+
208
+ ## 8. AI 生成代码规则
209
+
210
+ - `v-length` 优先用在 `el-input` 上,不要自己重复造截断逻辑
211
+ - 数值输入优先使用 `v-length.range`
212
+ - 权限按钮必须显式写 `id` 或稳定 class
213
+ - `.regex` 模式下不要使用带 `g` 的正则
214
+ - `v-permission` 不会自动响应权限切换,页面中不要假设它是响应式权限系统
215
+ - `v-event-unuse` / `v-event-use` 只控制鼠标交互,不处理键盘焦点逻辑
216
+
217
+ ## 9. 推荐 Prompt
218
+
219
+ ```text
220
+ 请生成一个 Vue2.7 页面,集中演示当前项目的 v-sline、v-length、v-permission、v-event-unuse、v-event-use,要求:
221
+ 1) v-length 覆盖普通限长、number、regex、range、range+int;
222
+ 2) 给出 sessionStorage.btnsPermission 的模拟注入代码;
223
+ 3) v-permission 同时演示 id、class、display 三种写法;
224
+ 4) 演示父级禁用事件、子级恢复事件;
225
+ 5) 使用 Element UI 的 ElInput、ElButton、ElCard;
226
+ 6) 不使用 TS,不虚构不存在的指令参数。
227
+ ```
228
+
229
+ ## 10. 标准模板
230
+
231
+ ```vue
232
+ <template>
233
+ <div style="padding: 20px;">
234
+ <el-card shadow="never">
235
+ <div style="width: 220px; margin-bottom: 16px;">
236
+ <span v-sline>{{ longText }}</span>
237
+ </div>
238
+
239
+ <el-form label-width="140px">
240
+ <el-form-item label="普通限长">
241
+ <el-input v-model="form.normal" v-length="10" />
242
+ </el-form-item>
243
+
244
+ <el-form-item label="数字限长">
245
+ <el-input v-model="form.mobile" v-length.number="11" />
246
+ </el-form-item>
247
+
248
+ <el-form-item label="正则校验">
249
+ <el-input v-model="form.code" v-length.regex="{ maxLength: 6, pattern: /^[A-Z0-9]*$/ }" />
250
+ </el-form-item>
251
+
252
+ <el-form-item label="数值范围">
253
+ <el-input v-model="form.score" v-length.range="{ min: 0, max: 100 }" />
254
+ </el-form-item>
255
+
256
+ <el-form-item label="整数范围">
257
+ <el-input v-model="form.age" v-length.range="{ min: 1, max: 120, int: true, maxLength: 3 }" />
258
+ </el-form-item>
259
+ </el-form>
260
+
261
+ <div style="margin-top: 16px;">
262
+ <el-button id="add_btn" v-permission type="primary">新增</el-button>
263
+ <el-button id="export_btn" v-permission.id.display>导出</el-button>
264
+ <el-button class="admin-btn" v-permission.class>管理员入口</el-button>
265
+ </div>
266
+
267
+ <div v-event-unuse style="margin-top: 16px; padding: 16px; border: 1px solid #ebeef5;">
268
+ <div v-event-use style="display: inline-block;" @click="handleChildClick">
269
+ 点我恢复交互
270
+ </div>
271
+ </div>
272
+ </el-card>
273
+ </div>
274
+ </template>
275
+
276
+ <script setup>
277
+ import { reactive, ref, onMounted } from 'vue'
278
+
279
+ const longText = ref('这是一段很长很长的文本,用于演示单行省略效果。')
280
+
281
+ const form = reactive({
282
+ normal: '',
283
+ mobile: '',
284
+ code: '',
285
+ score: '',
286
+ age: '',
287
+ })
288
+
289
+ const handleChildClick = () => {
290
+ console.log('子区域点击生效')
291
+ }
292
+
293
+ onMounted(() => {
294
+ sessionStorage.setItem('btnsPermission', JSON.stringify(['add_btn', 'admin-btn']))
295
+ })
296
+ </script>
297
+ ```
@@ -1,7 +1,5 @@
1
1
  <template>
2
2
  <div style="padding: 20px;">
3
- <h1>自定义指令演示 Demo</h1>
4
-
5
3
  <!-- v-sline 指令演示 -->
6
4
  <div class="demo-section">
7
5
  <h2>1. v-sline 指令 - 单行文本溢出省略</h2>