Commit fd68ba0bf93b6588ce270deec6e780f906e47fc7

Authored by Aaron
1 parent 35c37891
Exists in master and in 1 other branch legacy

新式表单支持事件内联与外联

examples/views/page/form-new/form-render.vue
@@ -8,14 +8,14 @@ @@ -8,14 +8,14 @@
8 <!-- 表单分组标题 --> 8 <!-- 表单分组标题 -->
9 <el-col :class="titleClass || 'eagle-form__group-title'" v-if="item.group.title" :span="24">{{ item.group.title || item.group }}</el-col> 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 </el-row> 12 </el-row>
13 </el-col> 13 </el-col>
14 <!-- 正常无分组表单项 --> 14 <!-- 正常无分组表单项 -->
15 <el-col v-else :span="item.span || 12" :key="index"> 15 <el-col v-else :span="item.span || 12" :key="index">
16 <el-form-item :label="item.label" :label-width="item.labelWidth || '120px'" :prop="item.fullKey" :rules="item.rules"> 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 </el-form-item> 19 </el-form-item>
20 </el-col> 20 </el-col>
21 </template> 21 </template>
@@ -28,6 +28,7 @@ export default { @@ -28,6 +28,7 @@ export default {
28 props: { 28 props: {
29 list: Array, 29 list: Array,
30 model: Object, 30 model: Object,
  31 + value: Object,
31 itemKey: String, 32 itemKey: String,
32 titleClass: String, 33 titleClass: String,
33 contentClass: String, 34 contentClass: String,
@@ -48,7 +49,7 @@ export default { @@ -48,7 +49,7 @@ export default {
48 }, 49 },
49 /** 50 /**
50 * @description 组件有值输入时的事件 51 * @description 组件有值输入时的事件
51 - * @param {Object} data { value => '组件值'; item => '表单项配置' } 52 + * @param {Object} data { value => 组件值; item => 表单项配置 }
52 */ 53 */
53 onInput({ value, item }) { 54 onInput({ value, item }) {
54 if (this.itemKey) { 55 if (this.itemKey) {
@@ -75,7 +76,30 @@ export default { @@ -75,7 +76,30 @@ export default {
75 */ 76 */
76 onFormItemChange(value) { 77 onFormItemChange(value) {
77 this.$emit('form-item-change', value); 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 </script> 105 </script>
examples/views/page/form-new/index.vue
1 <template> 1 <template>
2 <el-form ref="form" size="small" :class="formClass" :model="formModel"> 2 <el-form ref="form" size="small" :class="formClass" :model="formModel">
3 {{ formModel }} 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 {{ list }} 5 {{ list }}
6 </el-form> 6 </el-form>
7 </template> 7 </template>
8 8
9 <script> 9 <script>
10 import FormRender from './form-render'; 10 import FormRender from './form-render';
11 -import { cloneDeep } from 'lodash'; 11 +import { cloneDeep, set } from 'lodash';
12 12
13 export default { 13 export default {
14 name: 'FormNew', 14 name: 'FormNew',
@@ -97,6 +97,16 @@ export default { @@ -97,6 +97,16 @@ export default {
97 }; 97 };
98 setFormModelValue(Object.keys(value).map(key => ({ key, value: value[key] }))); 98 setFormModelValue(Object.keys(value).map(key => ({ key, value: value[key] })));
99 this.formModel = formModel; 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,13 +56,30 @@ export default {
56 { 56 {
57 group: { title: 'A栋', span: 24 }, 57 group: { title: 'A栋', span: 24 },
58 list: [ 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 group: { title: 'B栋', span: 24, key: 'bside' }, 69 group: { title: 'B栋', span: 24, key: 'bside' },
64 list: [ 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 ],