Skip to content

Commit febc7d9

Browse files
committed
feat: support custom component
re chenquincy#5
1 parent 343dcee commit febc7d9

File tree

15 files changed

+266
-42
lines changed

15 files changed

+266
-42
lines changed

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,15 @@ export default {
8383
- Support **multi-level form** for `Object `/ `Array` / `Hashmap`
8484
- Support data **validation**
8585
- **Multi-Languages** support
86+
- Support **custom component**
8687

8788
## Todo
8889

8990
**vue-dynamic-form-component** can do more. There are a few things that it currently doesn't support but are planned:
9091

9192
- [x] Custom component props
92-
- [ ] Custom component event
93-
- [ ] Support more component
94-
- [x] textarea
95-
- [ ] file upload
93+
- [x] Custom component event
94+
- [x] Custom component
9695
- [ ] Custom theme
9796
- [ ] Value change event
9897

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<template>
2+
<dynamic-form
3+
v-model="data"
4+
:descriptors="descriptors">
5+
</dynamic-form>
6+
</template>
7+
8+
<script>
9+
export default {
10+
data () {
11+
return {
12+
descriptors: {
13+
image: {
14+
type: 'url',
15+
required: true,
16+
message: 'please upload an image',
17+
component: {
18+
name: 'el-upload',
19+
children: [
20+
{ name: 'el-button', children: 'click to upload', props: { type: 'primary', plain: true, size: 'small' } }
21+
],
22+
props: {
23+
action: 'https://jsonplaceholder.typicode.com/posts/',
24+
onError: function (error, file, fileList) {
25+
console.log('upload error ==> ', error)
26+
}
27+
}
28+
}
29+
}
30+
},
31+
data: {}
32+
}
33+
}
34+
}
35+
</script>

docs/.vuepress/components/home-demo.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
<dynamic-form
33
ref="dynamic-form"
44
v-model="data"
5-
:descriptors="descriptors">
5+
:descriptors="descriptors"
6+
:showOuterError="false">
67
<template slot="operations">
78
<el-button @click="reset">Reset</el-button>
89
<el-button type="primary" @click="validate" plain>Validate</el-button>

docs/.vuepress/config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ module.exports = {
66
'/': {
77
lang: 'en-US',
88
title: 'vue-dynamic-form-component',
9-
description: 'Vue dynamic nested form component. Support nested Object/Hashmap/Array.'
9+
description: 'Vue dynamic nested form component. Support nested Object/Hashmap/Array. Can custom component yourself.'
1010
},
1111
'/zh/': {
1212
lang: 'zh-CN',
1313
title: 'vue-dynamic-form-component',
14-
description: 'Vue动态嵌套表单组件,支持嵌套对象/Hashmap/数组'
14+
description: 'Vue动态嵌套表单组件,支持嵌套对象/Hashmap/数组, 可自定义表单组件'
1515
}
1616
},
1717
themeConfig: {

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ meta:
99
- name: google-site-verification
1010
content: -lX8u-MYYDkf5y6QhZWJqZoDxVkmAu004XwR3ynRwFg
1111
features:
12-
- title: Generate form by descriptors
12+
- title: Generate form by descriptors Or custom component
1313
details: Write only data's descriptor(extend from async-validate), then automatically generate form(use element-ui)
1414
- title: Support almost all data type with validation
1515
details: Support almost all data type and normal data validation(email, url, ... etc)

docs/api/descriptors/README.md

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
## descriptor
1010

1111
::: tip Warm Prompt
12-
**descriptor** can be `object` or `array`, but the `fields`, `defaultFields`, `label`, `placeholder`, `hidden`, `disabled`, `options`, `autocomplete` props should be brother props with `type`. In addition, there is only one object include `type` prop in array.
12+
**descriptor** can be `object` or `array`, but the `fields`, `defaultFields`, `label`, `hidden`, `disabled`, `options`, `component` props should be brother props with `type`. In addition, there is only one object include `type` prop in array.
1313
:::
1414

1515
### type
1616

1717
`string`, declare the type of data's field, include common data type.
1818

19+
::: warning 注意
20+
21+
Note that [descriptor.component.name](/zh/api/descriptors/#props) has higher priority, the follow rules are invalid if `descriptor.component.name` is not null.
22+
:::
23+
1924
| Value | Description | Component |
2025
| --------- | ------------------------------------------------------------ | ------------------- |
2126
| `string` | Must be a string | `el-input` |
@@ -36,10 +41,6 @@
3641

3742
`string`, field's label in form, should be declared with `type` in the same object.
3843

39-
### props
40-
41-
`object` type, it will be the value of input component's `v-bind` prop(input component refer to [descriptor.type](/api/descriptors/#type)). You can custom the component with this option, there are some common prop like: `placeholder`, `disabled`, ... , etc. Other props of component refer to [element-ui](https://element.faas.ele.me/#/en-US/component/installation).
42-
4344
### hidden
4445

4546
`boolean` , whether hidden the input component of value, should be declared with `type` in the same object. Note that the hidden value still will be validated while validating.
@@ -206,3 +207,43 @@ const descriptors = {
206207
}
207208
```
208209

210+
### component
211+
212+
Provided for user to custom the component easily, it can custom the component's content, props and events.
213+
214+
``` js
215+
// component demo
216+
{
217+
name: 'el-button',
218+
props: {
219+
type: 'primary',
220+
size: 'small'
221+
},
222+
events: {
223+
click () {
224+
console.log('button click')
225+
}
226+
}
227+
}
228+
```
229+
230+
#### name
231+
232+
`string` type, custom to use which element or component.
233+
234+
#### props
235+
236+
`object` type, it will be the value of input component's `v-bind` prop(input component refer to [descriptor.type](/api/descriptors/#type)). You can custom the component props with this option, there are some common props like: `placeholder`, `disabled`, ... , etc. Other props of component refer to [element-ui](https://element.faas.ele.me/#/en-US/component/installation). Note that it will be the value of the custom component's `v-bind` prop, if `component.name` is not null.
237+
238+
#### events
239+
240+
`object` type, it will be the value of input component's `v-on` prop(input component refer to [descriptor.type](/api/descriptors/#type)). You can custom the component props with this option, there are some common prop like: `placeholder`, `disabled`, ... , etc. Other props of component refer to [element-ui](https://element.faas.ele.me/#/en-US/component/installation). Note that it will be the value of the custom component's `v-on` prop, if `component.name` is not null.
241+
242+
#### children
243+
244+
`children` is used to custom the content of component. It has two types:
245+
246+
- `string` : the content is plain text. It will be inserted with `span` element
247+
- `array[component | string]` : the content has more than one element, the array item has two types:
248+
- `component` : same structure with [component](/api/descriptors/#component)
249+
- `string` : the item is plain text. It will be inserted with `span` element

docs/getting-started/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,19 @@ Special prop `label`, `fields`, `defaultField` , ...etc should be used with `typ
125125

126126
<<<@/docs/.vuepress/components/custom-validator.vue
127127

128+
### Custom Component
129+
130+
::: tip Warm Prompt
131+
132+
To custom component, you should ensure `version >= 2.5.0`
133+
:::
134+
135+
**vue-dynamic-form-component** has components for common data type inside, so you don't need to custom the component generally. But sometimes, we need to custom the component, such as upload a file. To meet these scenes, I provide a way to custom the component. Usage like this:
136+
137+
<code-demo name="custom-component" lang="en_US"></code-demo>
138+
139+
<<<@/docs/.vuepress/components/custom-component.vue
140+
128141
### Form Operations
129142

130143
**vue-dynamic-form-component** provides some common methods to operate form, you can use them with `operations` slot.

docs/guide/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Support **nested form** for `Object `/ `Array` / `Hashmap`
1010
- Support data **validation**
1111
- **Multi-Languages** support
12+
- Support **custom component**
1213

1314
## Question
1415

docs/zh/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ meta:
77
- name: keywords
88
content: vue 动态 嵌套 表单 多级 组件 vue-dynamic-form vue-dynamic-form-component
99
features:
10-
- title: 使用descriptors生成表单
10+
- title: 使用descriptors生成表单或自定义组件
1111
details: 只需要提供目标数据的descriptor(基于async-validator扩展),就可以自动生成对应的表单元素(基于element-ui)
1212
- title: 支持绝大部分数据类型及其校验
1313
details: 支持绝大部分数据类型、常见类型校验(如:email、url等)

docs/zh/api/descriptors/README.md

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
## descriptor
88

99
::: warning 注意
10-
**descriptor** 可以是对象或者数组,但是,当 **descriptor** 为数组时,与数据类型定义有关的属性( `fields``defaultFields`)和扩展属性(`label``placeholder``hidden``disabled``options``autocomplete`) 需和 `type` 属性在同一对象中,并且数组中有且仅有一个包含 `type` 属性的对象。
10+
**descriptor** 可以是对象或者数组,但是,当 **descriptor** 为数组时,与数据类型定义有关的属性( `fields``defaultFields`)和扩展属性(`label``hidden``disabled``options``component`) 需和 `type` 属性在同一对象中,并且数组中有且仅有一个包含 `type` 属性的对象。
1111
:::
1212

1313
### type
1414

1515
`string` 类型,表示字段类型,包含常见的数据类型
1616

17+
::: warning 注意
18+
[descriptor.component.name](/zh/api/descriptors/#props) 优先级更高,当 `descriptor.component.name` 不为空时,以下规则不生效
19+
:::
20+
1721
|| 说明 | 对应组件 |
1822
| --------- | ------------------------------------------------------------ | ------------------- |
1923
| `string` | 字符串类型 | `el-input` |
@@ -34,10 +38,6 @@
3438

3539
`string` 类型,表单中对应字段的label值,需和 `type` 在同一个对象中
3640

37-
### props
38-
39-
`object` 类型,通过 `v-bind` 绑定到对应的 element-ui 输入组件(对应组件查阅 [descriptor.type](/zh/api/descriptors/#type)),可以通过该选项进行一些自定义操作,常见的属性有:`placeholder``disabled` 等,其他属性请查阅 [element-ui](https://element.faas.ele.me/#/zh-CN/component/installation) 对应组件文档
40-
4141
### hidden
4242

4343
`boolean` 类型,是否隐藏对应的输入组件,需和 `type` 在同一个对象中。需要注意的是,触发校验时,被隐藏的组件值依然会进行校验。
@@ -187,16 +187,56 @@ const descriptors = {
187187
{ type: 'string', required: true },
188188
{
189189
validator: function (rule, value, callback) {
190-
if (value.length < 5) {
191-
return callback(new Error('name should logger than 5'))
192-
}
190+
if (value.length < 5) {
191+
return callback(new Error('name should logger than 5'))
192+
}
193193
if (value.indexOf('/%$') !== -1) {
194194
return callback(new Error('name can not include /%$'))
195195
}
196-
return callback()
197-
}
196+
return callback()
197+
}
198198
}
199199
]
200200
}
201201
```
202202

203+
### component
204+
205+
为了方便使用者自定义组件提供的选项,可以自定义组件内容、属性和事件。
206+
207+
``` js
208+
// component 示例
209+
{
210+
name: 'el-button',
211+
props: {
212+
type: 'primary',
213+
size: 'small'
214+
},
215+
events: {
216+
click () {
217+
console.log('button click')
218+
}
219+
}
220+
}
221+
```
222+
223+
#### name
224+
225+
`string` 类型,自定义组件名或元素名
226+
227+
#### props
228+
229+
`object` 类型,当 `component.name` 为空时,通过 `v-bind` 绑定到对应的组件(对应组件查阅 [descriptor.type](/zh/api/descriptors/#type)),可以通过该选项进行属性自定义,常见的属性有:`placeholder``disabled` 等,其他对应组件属性请查阅 [element-ui](https://element.faas.ele.me/#/zh-CN/component/installation) 对应组件文档;当 `component.name` 不为空时,通过 `v-bind` 绑定到声明的组件上。
230+
231+
#### events
232+
233+
`object` 类型,当 `component.name` 为空时,通过 `v-on` 绑定到对应的组件(对应组件查阅 [descriptor.type](/zh/api/descriptors/#type)),可以通过该选项进行事件自定义,例如:`click``focus` 等,其他对应组件事件请查阅 [element-ui](https://element.faas.ele.me/#/zh-CN/component/installation) 对应组件文档;当 `component.name` 不为空时,通过 `v-on` 绑定到声明的组件上。
234+
235+
#### children
236+
237+
`children` 用于自定义组件内容,它有两种类型:
238+
239+
- `string` :表示内容为纯文本,使用 `span` 标签插入
240+
- `array[component | string]` : 表示组件内容有多个元素,数组元素有两种类型:
241+
- `component` : 结构和 [component](/zh/api/descriptors/#component) 相同
242+
- `string` : 表示纯文本元素,使用 `span` 标签插入

0 commit comments

Comments
 (0)