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 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 ],
... ...