Commit fd68ba0bf93b6588ce270deec6e780f906e47fc7
1 parent
35c37891
Exists in
master
and in
1 other branch
新式表单支持事件内联与外联
Showing
3 changed files
with
59 additions
and
8 deletions
Show diff stats
examples/views/page/form-new/form-render.vue
| ... | ... | @@ -8,14 +8,14 @@ |
| 8 | 8 | <!-- 表单分组标题 --> |
| 9 | 9 | <el-col :class="titleClass || 'eagle-form__group-title'" v-if="item.group.title" :span="24">{{ item.group.title || item.group }}</el-col> |
| 10 | 10 | <!-- 递归本组件 --> |
| 11 | - <form-render :title-class="titleClass" :list="item.list" :model="itemKey ? model[itemKey] || {} : model" @item-change="onItemChange" @form-item-change="onFormItemChange" :itemKey="item.group.key"></form-render> | |
| 11 | + <form-render :title-class="titleClass" :list="item.list" :value="value" :model="itemKey ? model[itemKey] || {} : model" @item-change="onItemChange" @form-item-change="onFormItemChange" :itemKey="item.group.key" @item-update="onItemUpdate"></form-render> | |
| 12 | 12 | </el-row> |
| 13 | 13 | </el-col> |
| 14 | 14 | <!-- 正常无分组表单项 --> |
| 15 | 15 | <el-col v-else :span="item.span || 12" :key="index"> |
| 16 | 16 | <el-form-item :label="item.label" :label-width="item.labelWidth || '120px'" :prop="item.fullKey" :rules="item.rules"> |
| 17 | 17 | <!-- 自定义组件 --> |
| 18 | - <component :is="item.type" :value="itemValue(item)" @input="v => onInput({ value: v, item })"></component> | |
| 18 | + <component :is="item.type" :value="itemValue(item)" @input="v => onInput({ value: v, item })" v-on="bindItemEvent(item)"></component> | |
| 19 | 19 | </el-form-item> |
| 20 | 20 | </el-col> |
| 21 | 21 | </template> |
| ... | ... | @@ -28,6 +28,7 @@ export default { |
| 28 | 28 | props: { |
| 29 | 29 | list: Array, |
| 30 | 30 | model: Object, |
| 31 | + value: Object, | |
| 31 | 32 | itemKey: String, |
| 32 | 33 | titleClass: String, |
| 33 | 34 | contentClass: String, |
| ... | ... | @@ -48,7 +49,7 @@ export default { |
| 48 | 49 | }, |
| 49 | 50 | /** |
| 50 | 51 | * @description 组件有值输入时的事件 |
| 51 | - * @param {Object} data { value => '组件值'; item => '表单项配置' } | |
| 52 | + * @param {Object} data { value => 组件值; item => 表单项配置 } | |
| 52 | 53 | */ |
| 53 | 54 | onInput({ value, item }) { |
| 54 | 55 | if (this.itemKey) { |
| ... | ... | @@ -75,7 +76,30 @@ export default { |
| 75 | 76 | */ |
| 76 | 77 | onFormItemChange(value) { |
| 77 | 78 | this.$emit('form-item-change', value); |
| 78 | - } | |
| 79 | + }, | |
| 80 | + /** | |
| 81 | + * @description 当表单项有手动更新时的事件 | |
| 82 | + * @param {Any} 表单项值 | |
| 83 | + */ | |
| 84 | + onItemUpdate(value) { | |
| 85 | + this.$emit('item-update', value); | |
| 86 | + }, | |
| 87 | + /** | |
| 88 | + * @description 绑定表单项事件 | |
| 89 | + * @param {Object} item 表单项配置 | |
| 90 | + * @returns {Function} 事件函数 | |
| 91 | + */ | |
| 92 | + bindItemEvent(item) { | |
| 93 | + if (item.on) { | |
| 94 | + if (typeof item.on === 'function') { | |
| 95 | + return item.on({ model: this.value, update: ({ name, value }) => this.$emit('item-update', { name, value }) }); | |
| 96 | + } else { | |
| 97 | + return item.on | |
| 98 | + } | |
| 99 | + } else { | |
| 100 | + return undefined | |
| 101 | + } | |
| 102 | + }, | |
| 79 | 103 | } |
| 80 | 104 | } |
| 81 | 105 | </script> | ... | ... |
examples/views/page/form-new/index.vue
| 1 | 1 | <template> |
| 2 | 2 | <el-form ref="form" size="small" :class="formClass" :model="formModel"> |
| 3 | 3 | {{ formModel }} |
| 4 | - <form-render :title-class="titleClass" :content-class="contentClass" :list="formList" :model="model" @item-change="onItemChange" @form-item-change="onFormItemChange"></form-render> | |
| 4 | + <form-render :title-class="titleClass" :content-class="contentClass" :list="formList" :value="model" :model="model" @item-change="onItemChange" @form-item-change="onFormItemChange" @item-update="onItemUpdate"></form-render> | |
| 5 | 5 | {{ list }} |
| 6 | 6 | </el-form> |
| 7 | 7 | </template> |
| 8 | 8 | |
| 9 | 9 | <script> |
| 10 | 10 | import FormRender from './form-render'; |
| 11 | -import { cloneDeep } from 'lodash'; | |
| 11 | +import { cloneDeep, set } from 'lodash'; | |
| 12 | 12 | |
| 13 | 13 | export default { |
| 14 | 14 | name: 'FormNew', |
| ... | ... | @@ -97,6 +97,16 @@ export default { |
| 97 | 97 | }; |
| 98 | 98 | setFormModelValue(Object.keys(value).map(key => ({ key, value: value[key] }))); |
| 99 | 99 | this.formModel = formModel; |
| 100 | + }, | |
| 101 | + /** | |
| 102 | + * @description 手动更新某一表单项的值 | |
| 103 | + * @param {Object} { name => 表单项key,可嵌套; value => 更新的值 } | |
| 104 | + * @example { name: 'a.b.c', value: 123 } | |
| 105 | + */ | |
| 106 | + onItemUpdate({ name, value }) { | |
| 107 | + const newModel = cloneDeep(this.model); | |
| 108 | + set(newModel, name, value); | |
| 109 | + this.$emit('input', newModel); | |
| 100 | 110 | } |
| 101 | 111 | } |
| 102 | 112 | } | ... | ... |
examples/views/page/other.vue
| ... | ... | @@ -56,13 +56,30 @@ export default { |
| 56 | 56 | { |
| 57 | 57 | group: { title: 'A栋', span: 24 }, |
| 58 | 58 | list: [ |
| 59 | - { type: 'el-input', label: '人数', key: 'anumber', span: 24 }, | |
| 59 | + { type: 'el-input-number', label: '人数', key: 'anumber', span: 24, | |
| 60 | + on: { | |
| 61 | + change(value) { | |
| 62 | + console.log(value); | |
| 63 | + } | |
| 64 | + } | |
| 65 | + }, | |
| 60 | 66 | ], |
| 61 | 67 | }, |
| 62 | 68 | { |
| 63 | 69 | group: { title: 'B栋', span: 24, key: 'bside' }, |
| 64 | 70 | list: [ |
| 65 | - { type: 'el-input', label: '人数', key: 'bnumber', span: 24 }, | |
| 71 | + { type: 'el-input-number', label: '人数', key: 'bnumber', span: 24, | |
| 72 | + on({ model, update }) { | |
| 73 | + return { | |
| 74 | + change(value) { | |
| 75 | + if (value === 18 && model.age === 18) { | |
| 76 | + // TODO update后本值不变的BUG | |
| 77 | + update({ name: 'location.areaName', value: 'haha' }); | |
| 78 | + } | |
| 79 | + } | |
| 80 | + } | |
| 81 | + } | |
| 82 | + }, | |
| 66 | 83 | ], |
| 67 | 84 | } |
| 68 | 85 | ], | ... | ... |