Commit 81d90a8c582c72f91b02dcc0e7d77e0a63c7231e

Authored by 刘汉宸
1 parent 32ccef0e

feat: 支持Function动态Props

packages/filter/index.vue
1 <template> 1 <template>
2 - <z-form v-model="model" class="zee-filter" :list="formattedList" :span="span" :labelWidth="labelWidth" :colClass="colVisibleRender" :size="size" :formProps="formProps"> 2 + <z-form v-model="model" class="zee-filter" :list="formattedList" :span="span" :labelWidth="labelWidth" :colClass="colVisibleRender" :size="size" :formProps="formProps" :params="params">
3 <div slot="$operation" class="zee-filter__button-group"> 3 <div slot="$operation" class="zee-filter__button-group">
4 <el-button-group :size="size"> 4 <el-button-group :size="size">
5 <el-button type="primary" @click="handleSearch" :loading="loading" icon="el-icon-search"><span>查询</span></el-button> 5 <el-button type="primary" @click="handleSearch" :loading="loading" icon="el-icon-search"><span>查询</span></el-button>
@@ -20,7 +20,7 @@ export default { @@ -20,7 +20,7 @@ export default {
20 list: Array, 20 list: Array,
21 labelWidth: { 21 labelWidth: {
22 type: String, 22 type: String,
23 - default: '80px', 23 + default: '110px',
24 }, 24 },
25 size: { 25 size: {
26 type: String, 26 type: String,
@@ -39,6 +39,7 @@ export default { @@ -39,6 +39,7 @@ export default {
39 type: Object, 39 type: Object,
40 default: () => ({}), 40 default: () => ({}),
41 }, 41 },
  42 + params: Object,
42 }, 43 },
43 data() { 44 data() {
44 return { 45 return {
packages/form/form-render.vue
@@ -56,8 +56,8 @@ @@ -56,8 +56,8 @@
56 item.type($createElement, { 56 item.type($createElement, {
57 model: value, 57 model: value,
58 config: { 58 config: {
59 - props: { ...item.props, value: itemValue(item) },  
60 - style: item.style || { maxWidth: '100%' }, 59 + props: { ...propsFormatter(item.props), value: itemValue(item) },
  60 + style: item.style || { width: '100%' },
61 on: { 61 on: {
62 ...bindItemEvent(item), 62 ...bindItemEvent(item),
63 input: v => onInput({ value: v, item }), 63 input: v => onInput({ value: v, item }),
@@ -72,8 +72,8 @@ @@ -72,8 +72,8 @@
72 :value="itemValue(item)" 72 :value="itemValue(item)"
73 @input="v => onInput({ value: v, item })" 73 @input="v => onInput({ value: v, item })"
74 v-on="bindItemEvent(item)" 74 v-on="bindItemEvent(item)"
75 - v-bind="item.props"  
76 - :style="item.style || { maxWidth: '100%' }" 75 + v-bind="propsFormatter(item.props)"
  76 + :style="item.style || { width: '100%' }"
77 ></component> 77 ></component>
78 </template> 78 </template>
79 </el-form-item> 79 </el-form-item>
@@ -101,6 +101,7 @@ export default { @@ -101,6 +101,7 @@ export default {
101 groupClass: String, 101 groupClass: String,
102 type: String, 102 type: String,
103 span: Number, 103 span: Number,
  104 + params: Object,
104 }, 105 },
105 computed: { 106 computed: {
106 rowComponent() { 107 rowComponent() {
@@ -202,10 +203,21 @@ export default { @@ -202,10 +203,21 @@ export default {
202 bindItemVisible(item, type) { 203 bindItemVisible(item, type) {
203 const visible = item[type]; 204 const visible = item[type];
204 if (typeof visible === 'function') { 205 if (typeof visible === 'function') {
205 - return visible(this.model); 206 + return visible(this.model, this.params || {});
206 } 207 }
207 return item[type] !== false; 208 return item[type] !== false;
208 }, 209 },
  210 + /**
  211 + * @description 格式化props属性
  212 + * @param {Object|Function} props 属性或属性对象
  213 + * @returns {Object} 格式化的属性
  214 + */
  215 + propsFormatter(props) {
  216 + if (typeof props === 'function') {
  217 + return props(this.model, this.params || {});
  218 + }
  219 + return props || {};
  220 + },
209 }, 221 },
210 }; 222 };
211 </script> 223 </script>
packages/form/index.vue
1 -<style>  
2 -.zee-form__flex-wrap {  
3 - display: flex;  
4 - flex-wrap: wrap;  
5 - width: 100%;  
6 -}  
7 -.zee-form__group-title {  
8 - font-weight: bold;  
9 - padding: 15px 5px;  
10 - border-bottom: 1px solid #d9d9d9;  
11 - margin-bottom: 15px;  
12 -}  
13 -.zee-form__group-content {  
14 - margin: 15px 0px; 1 +<style lang="scss">
  2 +.zee-form {
  3 + &__flex-wrap {
  4 + display: flex;
  5 + flex-wrap: wrap;
  6 + width: 100%;
  7 + }
  8 + &__group-title {
  9 + font-weight: bold;
  10 + padding: 15px 5px;
  11 + border-bottom: 1px solid #d9d9d9;
  12 + margin-bottom: 15px;
  13 + }
  14 + &__group-content {
  15 + margin: 15px 0px;
  16 + }
  17 + &__footer {
  18 + padding-top: 10px;
  19 + display: flex;
  20 + align-items: center;
  21 + justify-content: center;
  22 + }
15 } 23 }
16 </style> 24 </style>
17 25
18 <template> 26 <template>
19 - <el-form ref="form" :size="size" :class="formClass" :model="formModel" :label-width="labelWidth" :label-position="labelPosition || labelWidth ? 'right' : 'top'" v-bind="formProps"> 27 + <el-form
  28 + ref="form"
  29 + class="zee-form"
  30 + :size="size"
  31 + :class="formClass"
  32 + :model="formModel"
  33 + :label-width="labelWidth"
  34 + :label-position="labelPosition || labelWidth ? 'right' : 'top'"
  35 + v-bind="formProps"
  36 + >
20 <form-render 37 <form-render
21 :title-class="titleClass" 38 :title-class="titleClass"
22 :content-class="contentClass" 39 :content-class="contentClass"
@@ -28,12 +45,16 @@ @@ -28,12 +45,16 @@
28 :model="model" 45 :model="model"
29 :span="span" 46 :span="span"
30 :type="type" 47 :type="type"
  48 + :params="params"
31 @item-change="onItemChange" 49 @item-change="onItemChange"
32 @form-item-change="onFormItemChange" 50 @form-item-change="onFormItemChange"
33 @item-update="onItemUpdate" 51 @item-update="onItemUpdate"
34 > 52 >
35 <slot v-for="key in slotKeys" :name="key" :slot="key"></slot> 53 <slot v-for="key in slotKeys" :name="key" :slot="key"></slot>
36 </form-render> 54 </form-render>
  55 + <div v-if="$scopedSlots.footer" class="zee-form__footer">
  56 + <slot name="footer" :size="size" :validate="validate" :reset="reset" :model="model"></slot>
  57 + </div>
37 </el-form> 58 </el-form>
38 </template> 59 </template>
39 60
@@ -68,6 +89,7 @@ export default { @@ -68,6 +89,7 @@ export default {
68 type: Object, 89 type: Object,
69 default: () => ({}), 90 default: () => ({}),
70 }, 91 },
  92 + params: Object,
71 }, 93 },
72 data() { 94 data() {
73 return { 95 return {
@@ -136,8 +158,11 @@ export default { @@ -136,8 +158,11 @@ export default {
136 * @description 校验表单 158 * @description 校验表单
137 */ 159 */
138 validate() { 160 validate() {
139 - this.$refs.form.validate(valid => {  
140 - this.$emit('validate', valid, this.model); 161 + return new Promise(resolve => {
  162 + this.$refs.form.validate(valid => {
  163 + this.$emit('validate', valid, this.model);
  164 + return resolve(valid);
  165 + });
141 }); 166 });
142 }, 167 },
143 /** 168 /**
packages/scheme/index.vue
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 @search="search" 19 @search="search"
20 :loading="loading" 20 :loading="loading"
21 v-bind="filterProps" 21 v-bind="filterProps"
  22 + :params="_slotScope"
22 ></z-filter> 23 ></z-filter>
23 </div> 24 </div>
24 <!-- 按钮区 --> 25 <!-- 按钮区 -->
@@ -70,7 +71,7 @@ @@ -70,7 +71,7 @@
70 <el-popconfirm confirmButtonText="确定" cancelButtonText="取消" title="确定删除吗?" placement="top" @onConfirm="handleDelete([slotScope.row])"> 71 <el-popconfirm confirmButtonText="确定" cancelButtonText="取消" title="确定删除吗?" placement="top" @onConfirm="handleDelete([slotScope.row])">
71 <el-button slot="reference" type="text" icon="el-icon-delete" title="删除"></el-button> 72 <el-button slot="reference" type="text" icon="el-icon-delete" title="删除"></el-button>
72 </el-popconfirm> 73 </el-popconfirm>
73 - <slot name="operation-button" v-bind="_slotScope"></slot> 74 + <slot name="operation-button" v-bind="{ ..._slotScope, slotScope }"></slot>
74 </div> 75 </div>
75 </el-table-column> 76 </el-table-column>
76 </template> 77 </template>
@@ -116,43 +117,47 @@ @@ -116,43 +117,47 @@
116 <template v-if="dialogRender"> 117 <template v-if="dialogRender">
117 <!-- 自定义弹出框内容 --> 118 <!-- 自定义弹出框内容 -->
118 <slot v-if="hadSlot(`dialog-${dialogType}`)" :name="`dialog-${dialogType}`" :model="_formModel" v-bind="_slotScope"></slot> 119 <slot v-if="hadSlot(`dialog-${dialogType}`)" :name="`dialog-${dialogType}`" :model="_formModel" v-bind="_slotScope"></slot>
119 - <!-- 内置弹出框新增修改表单 -->  
120 - <template v-if="['new', 'edit'].includes(dialogType)">  
121 - <z-form  
122 - ref="form"  
123 - :value="_formModel"  
124 - :list="formList || listMap.form"  
125 - @input="onFormInput"  
126 - @validate="onFormValidate"  
127 - v-bind="{ span: 12, 'label-width': '80px', ...formProps }"  
128 - >  
129 - <!-- 表单自定义插槽 -->  
130 - <template v-for="item in renderList">  
131 - <template v-if="$scopedSlots[`form-${item.fullKey}`]">  
132 - <slot :slot="item.fullKey" :name="`form-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot>  
133 - </template>  
134 - </template>  
135 - </z-form>  
136 - </template>  
137 - <!-- 内置弹出框详情表单 -->  
138 <template v-else> 120 <template v-else>
139 - <z-form  
140 - ref="form"  
141 - class="zee-scheme__view"  
142 - :value="_formModel"  
143 - :list="viewList || listMap.form | viewTypeFilter | noRulesFilter"  
144 - v-bind="{ span: 12, 'label-width': '80px', ...viewProps }"  
145 - >  
146 - <!-- 详情自定义插槽渲染 -->  
147 - <template v-for="item in renderList">  
148 - <template v-if="$scopedSlots[`view-${item.fullKey}`]">  
149 - <slot :slot="item.fullKey" :name="`view-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot> 121 + <!-- 内置弹出框新增修改表单 -->
  122 + <template v-if="['new', 'edit'].includes(dialogType)">
  123 + <z-form
  124 + ref="form"
  125 + :value="_formModel"
  126 + :list="formList || listMap.form"
  127 + @input="onFormInput"
  128 + @validate="onFormValidate"
  129 + v-bind="{ span: 12, 'label-width': '110px', ...formProps }"
  130 + :params="_slotScope"
  131 + >
  132 + <!-- 表单自定义插槽 -->
  133 + <template v-for="item in renderList">
  134 + <template v-if="$scopedSlots[`form-${item.fullKey}`]">
  135 + <slot :slot="item.fullKey" :name="`form-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot>
  136 + </template>
150 </template> 137 </template>
151 - <template v-else-if="$scopedSlots[`render-${item.fullKey}`]">  
152 - <slot :slot="item.fullKey" :name="`render-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot> 138 + </z-form>
  139 + </template>
  140 + <!-- 内置弹出框详情表单 -->
  141 + <template v-else>
  142 + <z-form
  143 + ref="form"
  144 + class="zee-scheme__view"
  145 + :value="_formModel"
  146 + :list="viewList || listMap.form | viewTypeFilter | noRulesFilter"
  147 + v-bind="{ span: 12, 'label-width': '110px', ...viewProps }"
  148 + :params="_slotScope"
  149 + >
  150 + <!-- 详情自定义插槽渲染 -->
  151 + <template v-for="item in renderList">
  152 + <template v-if="$scopedSlots[`view-${item.fullKey}`]">
  153 + <slot :slot="item.fullKey" :name="`view-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot>
  154 + </template>
  155 + <template v-else-if="$scopedSlots[`render-${item.fullKey}`]">
  156 + <slot :slot="item.fullKey" :name="`render-${item.fullKey}`" :value="get(_formModel, item.fullKey)" :row="_formModel" :model="_formModel" v-bind="_slotScope"></slot>
  157 + </template>
153 </template> 158 </template>
154 - </template>  
155 - </z-form> 159 + </z-form>
  160 + </template>
156 </template> 161 </template>
157 <!-- 内置弹出框新增修改按钮 --> 162 <!-- 内置弹出框新增修改按钮 -->
158 <div class="zee-scheme__dialog-button" v-if="['new', 'edit'].includes(dialogType)"> 163 <div class="zee-scheme__dialog-button" v-if="['new', 'edit'].includes(dialogType)">
@@ -336,8 +341,10 @@ export default { @@ -336,8 +341,10 @@ export default {
336 openDialog: this.openDialog, 341 openDialog: this.openDialog,
337 closeDialog: this.closeDialog, 342 closeDialog: this.closeDialog,
338 openView: this.openView, 343 openView: this.openView,
  344 + openEdit: this.openEdit,
339 handleDelete: this.handleDelete, 345 handleDelete: this.handleDelete,
340 size: this.size, 346 size: this.size,
  347 + dialogType: this.dialogType,
341 }; 348 };
342 }, 349 },
343 _alias() { 350 _alias() {
@@ -461,6 +468,7 @@ export default { @@ -461,6 +468,7 @@ export default {
461 .then(() => { 468 .then(() => {
462 this.$message.success('保存成功'); 469 this.$message.success('保存成功');
463 this.closeDialog(); 470 this.closeDialog();
  471 + this.search();
464 }) 472 })
465 .catch(() => { 473 .catch(() => {
466 this.$message.error('保存失败'); 474 this.$message.error('保存失败');
@@ -508,6 +516,7 @@ export default { @@ -508,6 +516,7 @@ export default {
508 getAPI(row) 516 getAPI(row)
509 .then(result => { 517 .then(result => {
510 this.editForm = result; 518 this.editForm = result;
  519 + this.$emit('update:formModel', result || {});
511 }) 520 })
512 .finally(() => { 521 .finally(() => {
513 this.dialogLoading = false; 522 this.dialogLoading = false;
@@ -535,6 +544,7 @@ export default { @@ -535,6 +544,7 @@ export default {
535 viewAPI(row) 544 viewAPI(row)
536 .then(result => { 545 .then(result => {
537 this.editForm = result; 546 this.editForm = result;
  547 + this.$emit('update:formModel', result || {});
538 }) 548 })
539 .finally(() => { 549 .finally(() => {
540 this.dialogLoading = false; 550 this.dialogLoading = false;
@@ -590,17 +600,18 @@ export default { @@ -590,17 +600,18 @@ export default {
590 // 关闭弹出框 600 // 关闭弹出框
591 closeDialog() { 601 closeDialog() {
592 this.dialogVisible = false; 602 this.dialogVisible = false;
  603 + this.dialogRender = false;
  604 + this.dialogType = 'none';
593 this.$emit('dialog-change', 'none'); 605 this.$emit('dialog-change', 'none');
594 }, 606 },
595 // 清空表单 607 // 清空表单
596 clearEditForm() { 608 clearEditForm() {
597 this.editForm = {}; 609 this.editForm = {};
  610 + this.$emit('update:formModel', {});
598 }, 611 },
599 // 弹出框关闭动画结束 612 // 弹出框关闭动画结束
600 onDialogClosed() { 613 onDialogClosed() {
601 this.clearEditForm(); 614 this.clearEditForm();
602 - this.dialogRender = false;  
603 - this.dialogType = 'none';  
604 }, 615 },
605 // 分页-每页个数 616 // 分页-每页个数
606 handleSizeChange(val) { 617 handleSizeChange(val) {