@neeloong/form 0.9.0 → 0.11.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/README.md +240 -81
- package/index.d.mts +613 -66
- package/index.js +611 -451
- package/index.min.js +8 -8
- package/index.min.mjs +6 -6
- package/index.mjs +610 -450
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
@neeloong/form
|
|
2
2
|
===================
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
相应式的实现,目前采用 [tc39/proposal-signals](https://github.com/tc39/proposal-signals) 的 [polyfill](https://github.com/proposal-signals/signal-polyfill.git)
|
|
4
|
+
`@neeloong/form` 是一个基于响应式数据绑定的表单渲染库,目前使用 [tc39/proposal-signals](https://github.com/tc39/proposal-signals) 的 [polyfill](https://github.com/proposal-signals/signal-polyfill.git)实现状态管理。其模板语法结合了声明式指令和灵活的变量管理,支持复杂表单的动态渲染和交互。
|
|
7
5
|
|
|
8
6
|
```js
|
|
9
7
|
|
|
@@ -70,74 +68,181 @@ store.value = defaultValue
|
|
|
70
68
|
const app = document.querySelector('#app');
|
|
71
69
|
render(store, layouts, app);
|
|
72
70
|
|
|
73
|
-
|
|
74
71
|
```
|
|
75
72
|
|
|
76
73
|
## API
|
|
77
74
|
|
|
78
|
-
- `Layout.parse(template, options)`
|
|
79
|
-
- `Store.create(schema)`
|
|
80
|
-
- `render(store, layouts,
|
|
75
|
+
- `Layout.parse(template, options)` 解析模板字符串,返回布局配置。
|
|
76
|
+
- `Store.create(schema)` 创建表单存储实例,绑定数据与 Schema。
|
|
77
|
+
- `render(store, layouts, parent)` 将表单渲染到指定 DOM 元素。
|
|
81
78
|
|
|
79
|
+
具体定义类型定义文件
|
|
82
80
|
|
|
83
81
|
## 模板语法
|
|
84
82
|
|
|
85
|
-
###
|
|
83
|
+
### 基础语法
|
|
84
|
+
|
|
85
|
+
#### 标签属性
|
|
86
|
+
- **指令属性**:以 `!` 开头,用于条件渲染、循环等。
|
|
87
|
+
- **增强指令**:以 `~` 开头,用于自定义功能扩展(如表单验证、动态行为)。
|
|
88
|
+
- **事件绑定**:以 `@` 开头,绑定事件处理函数。
|
|
89
|
+
- **属性绑定**:以 `:` 开头,绑定动态属性值。
|
|
90
|
+
|
|
91
|
+
#### 表达式语法
|
|
92
|
+
直接写在属性值中,支持 JavaScript 表达式。
|
|
93
|
+
|
|
94
|
+
```html
|
|
95
|
+
<div !text="a + b"></div>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### 属性绑定
|
|
86
99
|
|
|
87
100
|
```html
|
|
88
101
|
<div :id="dynamicId"></div>
|
|
89
102
|
```
|
|
90
103
|
|
|
91
|
-
|
|
104
|
+
#### 事件绑定
|
|
92
105
|
|
|
93
106
|
```html
|
|
94
|
-
<
|
|
107
|
+
<button @click="handleClick($event)">点击</button>
|
|
95
108
|
```
|
|
96
109
|
|
|
97
|
-
|
|
110
|
+
事件对象(如鼠标坐标、键盘键码)可通过 `$event` 获取。
|
|
98
111
|
|
|
99
112
|
```html
|
|
100
|
-
<
|
|
101
|
-
<h2 !else !if="b"></h2>
|
|
102
|
-
<h3 !else !if="c"></h3>
|
|
103
|
-
<p !else></p>
|
|
113
|
+
<input @input="value = $event.target.value">
|
|
104
114
|
```
|
|
105
115
|
|
|
106
|
-
###
|
|
116
|
+
### 数据绑定与变量
|
|
117
|
+
|
|
118
|
+
#### 变量声明
|
|
119
|
+
- **显式变量(`+var`)**:
|
|
120
|
+
在标签中声明局部变量,作用域仅限当前标签及子标签。
|
|
121
|
+
```html
|
|
122
|
+
<div +count="0"> <!-- 初始化 count 为 0 -->
|
|
123
|
+
<button @click="count += 1" v-text="count"></button>
|
|
124
|
+
</div>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- **别名(`*alias`)**:
|
|
128
|
+
为复杂表达式或字段设置别名,简化引用。
|
|
129
|
+
```html
|
|
130
|
+
<div *len="array$length" !text="len"></div> <!-- 别名 len 指向当前数组长度 -->
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **计算值(`*computed`)**:
|
|
134
|
+
动态计算表达式,值随依赖变量变化自动更新。
|
|
135
|
+
```html
|
|
136
|
+
<div *double="a * 2" !text="double"></div>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- **字段变量(`field$value`)**:
|
|
140
|
+
直接访问字段的原始值,例如:
|
|
141
|
+
```html
|
|
142
|
+
<input !value="a" !text="field$value"> <!-- field$value 是字段 field 的原始值 -->
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### **2.2 变量优先级**
|
|
146
|
+
变量优先级从高到低:
|
|
147
|
+
1. **显式变量(`+var`)与别名(`*alias`)**
|
|
148
|
+
3. **计算值(`*computed`)**
|
|
149
|
+
4. **字段变量(`field$value`)**
|
|
150
|
+
5. **全局变量(通过 `render` 的 `global` 参数传入)**
|
|
151
|
+
|
|
152
|
+
### 条件渲染(`!if` `!else`)
|
|
153
|
+
- **基本用法**:
|
|
154
|
+
```html
|
|
155
|
+
<div !if="a > 0">条件成立</div>
|
|
156
|
+
<div !else !if="b < 0">条件二成立</div>
|
|
157
|
+
<div !else>其他情况</div>
|
|
158
|
+
```
|
|
159
|
+
- **注意事项**:
|
|
160
|
+
- `!else` 必须与同级的 `!if` 同级,否则会被忽略。
|
|
161
|
+
- 嵌套条件需使用多个同级标签。
|
|
107
162
|
|
|
108
163
|
```html
|
|
109
|
-
<
|
|
164
|
+
<div !if="a">
|
|
165
|
+
<div !else !if="b"></div> <!-- !else 未与前一个 !if 同级,会被忽略 -->
|
|
166
|
+
</div>
|
|
110
167
|
```
|
|
111
168
|
|
|
112
|
-
###
|
|
169
|
+
### 循环与枚举渲染(`!enum`)
|
|
170
|
+
|
|
171
|
+
#### 基础用法
|
|
113
172
|
|
|
114
173
|
```html
|
|
115
|
-
<
|
|
174
|
+
<ul>
|
|
175
|
+
<li !enum="items" !text="$item"></li> <!-- items 是数组 -->
|
|
176
|
+
</ul>
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### 嵌套循环
|
|
180
|
+
|
|
181
|
+
```html
|
|
182
|
+
<div !enum="outerArray" *outerLen="$length">
|
|
183
|
+
<div !enum="innerArray">
|
|
184
|
+
<span !text="outerLen + ' + ' + $length"></span> <!-- 外层长度 + 内层长度 -->
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 循环中的变量作用域
|
|
190
|
+
|
|
191
|
+
每个循环项拥有独立作用域,变量互不影响。
|
|
192
|
+
```html
|
|
193
|
+
<ul>
|
|
194
|
+
<li !enum="items" +count="0">
|
|
195
|
+
<button @click="count += 1" v-text="count"></button> <!-- 每个按钮独立计数 -->
|
|
196
|
+
</li>
|
|
197
|
+
</ul>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 子属性
|
|
201
|
+
|
|
202
|
+
```html
|
|
203
|
+
<h1 !value="subField"></h1>
|
|
116
204
|
```
|
|
117
205
|
|
|
118
206
|
### 字段绑定
|
|
119
207
|
|
|
120
208
|
```html
|
|
121
|
-
<input !bind="
|
|
209
|
+
<input !bind="a" !placeholder="请输入值" />
|
|
122
210
|
```
|
|
211
|
+
- **双向绑定**:字段值与表单数据同步更新。
|
|
212
|
+
|
|
213
|
+
### 片段(`!fragment`)
|
|
123
214
|
|
|
124
|
-
|
|
215
|
+
包裹多标签内容,形成作用域。
|
|
125
216
|
|
|
126
217
|
```html
|
|
127
|
-
<
|
|
218
|
+
<span !fragment !if="a">
|
|
219
|
+
<p>内容1</p>
|
|
220
|
+
<p>内容2</p>
|
|
221
|
+
</span>
|
|
128
222
|
```
|
|
129
223
|
|
|
130
|
-
|
|
224
|
+
`!fragment` 所在的标签不会被渲染。
|
|
225
|
+
|
|
226
|
+
### 文本渲染(`!text`) 与 html 渲染(`!html`)
|
|
227
|
+
|
|
228
|
+
**`!text`**:渲染纯文本
|
|
131
229
|
|
|
132
230
|
```html
|
|
133
|
-
<
|
|
231
|
+
<div !text="a"></div>
|
|
134
232
|
```
|
|
135
233
|
|
|
234
|
+
- **`!html`**:渲染 HTML 内容(需确保内容安全)
|
|
235
|
+
|
|
136
236
|
```html
|
|
137
|
-
<div !html="
|
|
237
|
+
<div !html="safeHTML"></div>
|
|
138
238
|
```
|
|
139
239
|
|
|
140
|
-
|
|
240
|
+
若 `!text` 与 `!html` 同时存在,`!html` 会被忽略。
|
|
241
|
+
|
|
242
|
+
### 注释(`!comment`)
|
|
243
|
+
|
|
244
|
+
仅用于开发,对渲染无影响。
|
|
245
|
+
|
|
141
246
|
```html
|
|
142
247
|
<div !comment="注释内容"></div>
|
|
143
248
|
```
|
|
@@ -148,17 +253,28 @@ render(store, layouts, app);
|
|
|
148
253
|
<div *alias1="v1" *computed="v1 + v2"></div>
|
|
149
254
|
```
|
|
150
255
|
|
|
151
|
-
|
|
152
256
|
### 显式变量(局部变量)
|
|
153
257
|
|
|
154
258
|
```html
|
|
155
259
|
<div +var1="123"></div>
|
|
156
260
|
```
|
|
157
261
|
|
|
158
|
-
###
|
|
159
|
-
|
|
262
|
+
### 增强指令(`~`)
|
|
263
|
+
|
|
264
|
+
#### 自定义指令
|
|
265
|
+
|
|
266
|
+
通过参数注册自定义指令
|
|
267
|
+
|
|
268
|
+
- **使用增强指令**:
|
|
269
|
+
```html
|
|
160
270
|
<div ~en:attr="a" ~en@event="show($event)" ~en!bind="bindValue" ~en="value"></div>
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### 增强指令顺序
|
|
274
|
+
按标签中首次出现的顺序执行。
|
|
161
275
|
|
|
276
|
+
```html
|
|
277
|
+
<div ~a ~b ~c></div> <!-- 先执行 a,再 b,最后 c -->
|
|
162
278
|
```
|
|
163
279
|
|
|
164
280
|
### 各用法的优先级
|
|
@@ -169,69 +285,68 @@ render(store, layouts, app);
|
|
|
169
285
|
1. 条件: `!if` `!else`
|
|
170
286
|
1. 子属性: `!value`
|
|
171
287
|
1. 枚举: `!enum`
|
|
172
|
-
1.
|
|
173
|
-
1. 显式变量: `+变量`
|
|
288
|
+
1. 别名、计算名与显式变量: `*别名` `*计算名` `+变量`
|
|
174
289
|
1. 片段与模板调用: `!fragment`
|
|
175
290
|
1. 属性与事件: `:绑定属性` `@事件` `普通属性` `!bind`
|
|
176
291
|
1. 子内容: `!text` `!html`
|
|
177
292
|
1. 注释: `!comment`
|
|
178
293
|
|
|
179
|
-
|
|
180
294
|
### 变量
|
|
181
295
|
1. 字段扩展隐式属性
|
|
182
|
-
- `$value`
|
|
183
|
-
- `$state`
|
|
184
|
-
- `$store`
|
|
185
|
-
- `$schema`
|
|
186
|
-
- `$null`
|
|
187
|
-
- `$index`
|
|
188
|
-
- `$no`
|
|
189
|
-
- `$length`
|
|
190
|
-
- `$creatable`
|
|
191
|
-
- `$immutable`
|
|
192
|
-
- `$new`
|
|
193
|
-
- `$readonly`
|
|
194
|
-
- `$hidden`
|
|
195
|
-
- `$clearable`
|
|
196
|
-
- `$required`
|
|
197
|
-
- `$disabled`
|
|
198
|
-
- `$label`
|
|
199
|
-
- `$description`
|
|
200
|
-
- `$placeholder`
|
|
201
|
-
- `$min`
|
|
202
|
-
- `$max`
|
|
203
|
-
- `$step`
|
|
204
|
-
- `$minLength`
|
|
205
|
-
- `$maxLength`
|
|
206
|
-
- `$pattern`
|
|
207
|
-
- `$values`
|
|
208
|
-
- `$type`
|
|
209
|
-
- `$meta`
|
|
210
|
-
- `$component`
|
|
211
|
-
- `$kind`
|
|
212
|
-
- `$error`
|
|
213
|
-
- `$errors`
|
|
296
|
+
- `$value` 字段当前值
|
|
297
|
+
- `$state` 字段状态
|
|
298
|
+
- `$store` 只读 当前字段表单存储实例
|
|
299
|
+
- `$schema` 只读 字段的 Schema 定义
|
|
300
|
+
- `$null` 只读 是否为空元素
|
|
301
|
+
- `$index` 只读 当前项的索引
|
|
302
|
+
- `$no` 只读 数组项目的序号
|
|
303
|
+
- `$length` 只读 数组的长度、对象的成员数
|
|
304
|
+
- `$creatable` 只读 值是否可创建(`$new` 为 `true` 时,字段只读)
|
|
305
|
+
- `$immutable` 只读 值是否不可改变(`$new` 为 `false` 时,字段只读)
|
|
306
|
+
- `$new` 只读 是否新建项
|
|
307
|
+
- `$readonly` 只读 是否只读
|
|
308
|
+
- `$hidden` 只读 是否可隐藏
|
|
309
|
+
- `$clearable` 只读 是否可清除
|
|
310
|
+
- `$required` 只读 是否必填
|
|
311
|
+
- `$disabled` 只读 是否禁用字段
|
|
312
|
+
- `$label` 只读 字段的标签信息
|
|
313
|
+
- `$description` 只读 字段的描述信息
|
|
314
|
+
- `$placeholder` 只读 字段的占位符信息
|
|
315
|
+
- `$min` 只读 数值字段的最小值限制
|
|
316
|
+
- `$max` 只读 数值字段的最大值限制
|
|
317
|
+
- `$step` 只读 数值字段的步长
|
|
318
|
+
- `$minLength` 只读 最小长度
|
|
319
|
+
- `$maxLength` 只读 最大长度
|
|
320
|
+
- `$pattern` 只读 模式
|
|
321
|
+
- `$values` 只读 可选值
|
|
322
|
+
- `$type` 只读 字段类型
|
|
323
|
+
- `$meta` 只读 字段元信息
|
|
324
|
+
- `$component` 只读 自定义渲染组件信息
|
|
325
|
+
- `$kind` 只读 字段类别
|
|
326
|
+
- `$error` 只读 字段校验错误信息
|
|
327
|
+
- `$errors` 只读 所有校验错误列表
|
|
328
|
+
1. 数组字段扩展隐式函数(只在事件中可用)
|
|
329
|
+
- `$reset()` 重置数据
|
|
330
|
+
- `$validate()` 触发当前项的异步校验
|
|
331
|
+
- `$validate(true)` 触发当前项及其后代的异步校验
|
|
214
332
|
1. 数组字段扩展隐式函数(只在事件中可用)
|
|
215
|
-
- `$insert(index, value)`
|
|
216
|
-
- `$add(value)`
|
|
217
|
-
- `$remove(index)`
|
|
218
|
-
- `$move(from, to)`
|
|
219
|
-
- `$exchange(a, b)`
|
|
220
|
-
- `$reset()`
|
|
221
|
-
- `$validate()`
|
|
222
|
-
- `$validate(true)`
|
|
333
|
+
- `$insert(index, value)` 在指定索引插入值
|
|
334
|
+
- `$add(value)` :向数组末尾添加值。
|
|
335
|
+
- `$remove(index)` 删除指定索引的项
|
|
336
|
+
- `$move(from, to)` 移动数组项
|
|
337
|
+
- `$exchange(a, b)` 切换 a b 两项
|
|
223
338
|
1. 数组成员字段扩展隐式属性
|
|
224
|
-
- `$upMovable`
|
|
225
|
-
- `$downMovable`
|
|
339
|
+
- `$upMovable` 只读 是否可上移
|
|
340
|
+
- `$downMovable` 只读 是否可下移
|
|
226
341
|
1. 数组成员字段扩展隐式函数(只在事件中可用)
|
|
227
|
-
- `$remove()`
|
|
228
|
-
- `$upMove()`
|
|
229
|
-
- `$downMove()`
|
|
342
|
+
- `$remove()` 移除当前项
|
|
343
|
+
- `$upMove()` 上移当前项
|
|
344
|
+
- `$downMove()` 下移当前项
|
|
230
345
|
1. 上下文隐式变量
|
|
231
|
-
- '$store'
|
|
232
|
-
- '$root'
|
|
346
|
+
- '$store' 只读 当前表单存储实例。
|
|
347
|
+
- '$root' 只读 根上下文对象。
|
|
233
348
|
1. 当前范围及组件范围的所有字段(数组字段的成员除外,因为数组字段成员索引为数字,不符合标识符命名规则)都存在 `field$value` 及 `field$$value` 形式的变量
|
|
234
|
-
1.
|
|
349
|
+
1. 如果别名为字段的别名(如 `*alias="v"`),则也存在 `alias$value` 形式的变量
|
|
235
350
|
1. 当存在同名变量时,则会按照变量来源类型决定优先级,从高到低依次为:
|
|
236
351
|
1. 上下文隐式变量
|
|
237
352
|
1. 显式声明(如别名、计算名、显式变量),如果别名是字段的别名,则也包括 `alias$value` 形式的变量
|
|
@@ -239,3 +354,47 @@ render(store, layouts, app);
|
|
|
239
354
|
1. 字段声明,包括 `field$value` 及 `field$$value` 形式的变量
|
|
240
355
|
1. 在同一来源类型重复的变量名,再按照作用域处理
|
|
241
356
|
1. 同一作用域下的别名(或计算名)与显式变量重名时,由于会先处理别名,所以,显式变量会覆盖别名。
|
|
357
|
+
|
|
358
|
+
### 示例代码
|
|
359
|
+
|
|
360
|
+
#### 嵌套表单与循环
|
|
361
|
+
|
|
362
|
+
```html
|
|
363
|
+
<ul !enum="users">
|
|
364
|
+
<li !enum="user.orders">
|
|
365
|
+
<div !text="user.name"></div>
|
|
366
|
+
<div !text="order.amount"></div>
|
|
367
|
+
<button @click="$remove">删除</button>
|
|
368
|
+
</li>
|
|
369
|
+
</ul>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### 条件渲染与字段绑定
|
|
373
|
+
|
|
374
|
+
```html
|
|
375
|
+
<div !if="showForm">
|
|
376
|
+
<input !bind="username" !placeholder="用户名" />
|
|
377
|
+
<button @click="$submit">提交</button>
|
|
378
|
+
</div>
|
|
379
|
+
<div !else !text="暂无表单"></div>
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
#### 渲染一个带条件和循环的表单
|
|
383
|
+
|
|
384
|
+
```html
|
|
385
|
+
<div>
|
|
386
|
+
<h1 !text="title"></h1>
|
|
387
|
+
|
|
388
|
+
<div !if="showForm">
|
|
389
|
+
<form !enum="fields">
|
|
390
|
+
<div !enum="items">
|
|
391
|
+
<input !bind="value" !placeholder="placeholder">
|
|
392
|
+
</div>
|
|
393
|
+
</form>
|
|
394
|
+
</div>
|
|
395
|
+
<div !else !text="暂无数据"></div>
|
|
396
|
+
|
|
397
|
+
<!-- 添加按钮 -->
|
|
398
|
+
<button @click="$add('new item')">添加项</button>
|
|
399
|
+
</div>
|
|
400
|
+
```
|