Skip to content

Commit

Permalink
feat(@0.8.9): 优化GenerateFormItem内部绑定逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
BoBoooooo committed Mar 9, 2021
1 parent e9b0b1b commit 0d615ab
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 64 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "element-pro-crud",
"version": "0.8.8-17",
"version": "0.8.9",
"author": "BoBo<[email protected]>",
"main": "lib/ProCrud.umd.min.js",
"files": [
Expand Down
1 change: 0 additions & 1 deletion src/component/form-designer/src/GenerateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ export default class GenerateForm extends Vue {
field.rules.push({
message: `${field.name}必须填写`,
required: true,
trigger: 'blur',
});
}
}
Expand Down
82 changes: 26 additions & 56 deletions src/component/form-designer/src/GenerateFormItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-->
<template>
<el-form-item :rules="widget.rules || []"
:prop="widget.type == 'button' ? undefined : widget.model"
:prop="formElement.includes(widget.type) ? widget.model : undefined"
:label-width="widget.options.hiddenLabel ? '0' : labelWidth"
:class="widget.options.className">
<template #label>
Expand All @@ -31,7 +31,7 @@
<el-input
v-if="['number', 'integer', 'float'].includes(widget.options.dataType)"
:type="widget.options.dataType"
v-model.number="dataModel"
v-model.number="models[widget.model]"
:placeholder="widget.options.placeholder"
:readonly="readOnly || widget.options.readonly"
:disabled="readOnly || widget.options.disabled"
Expand All @@ -40,7 +40,7 @@
<el-input
v-else
type="text"
v-model="dataModel"
v-model="models[widget.model]"
:show-word-limit="widget.options.showWordLimit"
:maxlength="widget.options.maxLength"
:placeholder="widget.options.placeholder"
Expand Down Expand Up @@ -82,11 +82,11 @@
</h3>
</template>
<template v-if="widget.type == 'label'">
<p>{{ dataModel }}</p>
<p>{{ models[widget.model] }}</p>
</template>
<template v-if="widget.type == 'select'">
<el-select
v-model="dataModel"
v-model="models[widget.model]"
default-first-option
:disabled="readOnly || widget.options.disabled"
:readonly="readOnly || widget.options.readonly"
Expand All @@ -107,7 +107,7 @@
<el-input
type="textarea"
:autosize="{ minRows: 5 }"
v-model="dataModel"
v-model="models[widget.model]"
:show-word-limit="widget.options.showWordLimit"
:maxlength="widget.options.maxLength"
:disabled="readOnly || widget.options.disabled"
Expand All @@ -119,7 +119,7 @@

<template v-if="widget.type == 'number'">
<el-input-number
v-model="dataModel"
v-model="models[widget.model]"
:style="{ width: widget.options.width }"
:step="widget.options.step"
:disabled="readOnly || widget.options.disabled"
Expand All @@ -129,15 +129,15 @@
</template>

<template v-if="widget.type == 'radio'">
<el-radio-group v-model="dataModel" :style="{ width: widget.options.width }" :disabled="readOnly || widget.options.disabled">
<el-radio-group v-model="models[widget.model]" :style="{ width: widget.options.width }" :disabled="readOnly || widget.options.disabled">
<el-radio :style="{ display: widget.options.inline ? 'inline-block' : 'block' }" :label="item.value" v-for="(item, index) in optionsList" :key="index">
<template v-if="widget.options.showLabel">{{ item.label }}</template>
</el-radio>
</el-radio-group>
</template>

<template v-if="widget.type == 'checkbox'">
<el-checkbox-group v-model="dataModel" :style="{ width: widget.options.width }">
<el-checkbox-group v-model="models[widget.model]" :style="{ width: widget.options.width }">
<template v-if="!widget.options.buttonStyle">
<el-checkbox
:style="{ display: widget.options.inline ? 'inline-block' : 'block' }"
Expand All @@ -158,7 +158,7 @@

<template v-if="widget.type == 'time'">
<el-time-picker
v-model="dataModel"
v-model="models[widget.model]"
:is-range="widget.options.isRange"
:placeholder="widget.options.placeholder"
:start-placeholder="widget.options.startPlaceholder"
Expand All @@ -176,7 +176,7 @@

<template v-if="widget.type == 'date'">
<el-date-picker
v-model="dataModel"
v-model="models[widget.model]"
:type="widget.options.type"
:placeholder="widget.options.placeholder"
:start-placeholder="widget.options.startPlaceholder"
Expand All @@ -195,20 +195,20 @@
</template>

<template v-if="widget.type == 'rate'">
<el-rate v-model="dataModel" :max="widget.options.max" :disabled="readOnly || widget.options.disabled" :allow-half="widget.options.allowHalf"></el-rate>
<el-rate v-model="models[widget.model]" :max="widget.options.max" :disabled="readOnly || widget.options.disabled" :allow-half="widget.options.allowHalf"></el-rate>
</template>

<template v-if="widget.type == 'color'">
<el-color-picker v-model="dataModel" :disabled="readOnly || widget.options.disabled" :show-alpha="widget.options.showAlpha"></el-color-picker>
<el-color-picker v-model="models[widget.model]" :disabled="readOnly || widget.options.disabled" :show-alpha="widget.options.showAlpha"></el-color-picker>
</template>

<template v-if="widget.type == 'switch'">
<el-switch v-model="dataModel" :disabled="readOnly || widget.options.disabled"> </el-switch>
<el-switch v-model="models[widget.model]" :disabled="readOnly || widget.options.disabled"> </el-switch>
</template>

<template v-if="widget.type == 'slider'">
<el-slider
v-model="dataModel"
v-model="models[widget.model]"
:min="widget.options.min"
:max="widget.options.max"
:disabled="readOnly || widget.options.disabled"
Expand All @@ -221,17 +221,17 @@
<template v-if="widget.type == 'cascader'">
<el-cascader
ref="cascader"
v-model="models[widget.model]"
@visible-change="elCascaderOnlick"
@expand-change="elCascaderOnlick"
v-model="dataModel"
:disabled="readOnly || widget.options.disabled"
:clearable="widget.options.clearable"
:placeholder="widget.options.placeholder"
:style="{ width: widget.options.width }"
:separator="widget.options.separator == null ? '/' : widget.options.separator"
:options="optionsList"
filterable
:props="{ checkStrictly: widget.options.checkStrictly, multiple: widget.options.multiple }"
:props="{ checkStrictly: widget.options.checkStrictly, multiple: widget.options.multiple,expandTrigger: 'hover' }"
>
</el-cascader>
</template>
Expand All @@ -258,7 +258,7 @@
<!-- 目前暂时提供了几个常用props,有更多需要自行拓展 -->
<!-- 官网:https://vue-treeselect.js.org -->
<TreeSelect
v-model="dataModel"
v-model="models[widget.model]"
v-if="visible"
:placeholder="widget.options.placeholder"
:maxHeight="+widget.options.maxHeight"
Expand Down Expand Up @@ -286,7 +286,7 @@
</TreeSelect>
</template>
<template v-if="widget.type == 'richtext'">
<Tinymce :height="400" v-model="dataModel" :readonly="readOnly || widget.options.readonly"></Tinymce>
<Tinymce :height="400" v-model="models[widget.model]" :readonly="readOnly || widget.options.readonly"></Tinymce>
</template>
<template v-if="widget.type == 'upload'">
<!-- 附件上传(注意初始值prefill必须传入id) -->
Expand All @@ -299,7 +299,7 @@
></FileUpload>
</template>
<template v-if="widget.type === 'avatar'">
<AvatarUpload :readOnly="readOnly" :widget="widget" v-model="dataModel"></AvatarUpload>
<AvatarUpload :readOnly="readOnly" :widget="widget" v-model="models[widget.model]"></AvatarUpload>
</template>
<template v-if="widget.type === 'form'">
<GenerateSubForm :widget="widget"></GenerateSubForm>
Expand Down Expand Up @@ -356,6 +356,7 @@ import pieChart from './components/Charts/pieChart.vue';
import Echarts from './components/Charts/Echarts.vue';
import GenerateTabs from './components/Tabs/GenerateTabs.vue';
import AvatarUpload from './components/AvatarUpload/AvatarUpload.vue';
import { formElement } from './componentsConfig';

@Component({
components: {
Expand Down Expand Up @@ -412,27 +413,16 @@ export default class GenerateFormItem extends Vue {
})
readOnly!: boolean


// 当前组件对象
dataModel: string | number | null | object = this.models[this.widget.model] || null

copyOption: any = [] // 备份一份初始选项

visible = false

normalizer: any

formElement = formElement

initData() {
const { type, model } = this.widget;
// if (this.model) {
// // 多选组件需要初始化值为数组
// if (this.widget.options.multiple || 'cascader,checkbox'.includes(type)) {
// this.dataModel = typeof this.model === 'string' ? this.model.split(',') : this.model;
// } else {
// this.dataModel = this.model;
// }
// return;
// }
let normalizer;
// tree-select组件初始化
if (type === 'treeselect') {
Expand Down Expand Up @@ -463,7 +453,6 @@ export default class GenerateFormItem extends Vue {
}
}
this.normalizer = normalizer;
this.dataModel = this.models[model];
}

created() {
Expand Down Expand Up @@ -680,7 +669,9 @@ export default class GenerateFormItem extends Vue {
document.querySelectorAll('.el-cascader-node__label').forEach((el) => {
// eslint-disable-next-line func-names
(el as any).onclick = function () {
this.previousElementSibling.click();
if (this.previousElementSibling) {
this.previousElementSibling.click();
}
that.$refs.cascader.dropDownVisible = false;
};
});
Expand Down Expand Up @@ -709,27 +700,6 @@ export default class GenerateFormItem extends Vue {
this.$emit('selection-change', selection);
}

@Watch('dataModel')
dataModelHandler(val) {
this.$set(this.models, this.widget.model, val);
this.$emit('change', val);
}

@Watch('models', {
deep: true,
})
modelsHandler(val) {
const updateVal = val[this.widget.model];
if (updateVal !== this.dataModel) {
if (this.widget.options.multiple || 'cascader,checkbox'.includes(this.widget.type)) {
const value = val[this.widget.model];
this.dataModel = typeof value === 'string' ? value.split(',') : value;
} else {
this.dataModel = val[this.widget.model];
}
}
}

// 如果表格预设参数发生变化 自动刷新表格
@Watch('getTableParams', {
deep: true,
Expand Down
8 changes: 4 additions & 4 deletions src/component/form-designer/src/WidgetConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,6 @@
</Draggable>
</el-checkbox-group>
</template>
<template v-if="elementConfig.type == 'cascader'">
<el-input type="textarea" v-model="elementConfig.options.options"></el-input>
</template>
<div style="margin-left: 22px;" v-if="elementConfig.type !== 'cascader'">
<el-button size="mini" type="text" @click="handleAddOption">添加选项</el-button>
<el-button size="mini" type="text" @click="handleClearOption">清除默认选中项</el-button>
Expand Down Expand Up @@ -710,7 +707,10 @@ export default {
},
validateRequired(val) {
if (val) {
this.validator.required = { required: true, message: `${this.elementConfig.name}必须填写` };
this.validator.required = {
required: true,
message: `${this.elementConfig.name}必须填写`,
};
} else {
this.validator.required = null;
}
Expand Down
25 changes: 23 additions & 2 deletions src/component/form-designer/src/componentsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,13 +307,31 @@ export const basicComponents = [
width: '100%',
separator: '/',
placeholder: '',
required: false,
multiple: false,
disabled: false,
clearable: false,
checkStrictly: false,
remote: 'static',
remoteOptions: [],
options: [],
options: [
{
value: 'A',
label: 'A',
children: [
{
value: 'AA',
label: 'AA',
children: [
{
value: 'AAA',
label: 'AAA',
},
],
},
],
},
],
props: {
value: 'value',
label: 'label',
Expand Down Expand Up @@ -392,6 +410,7 @@ export const basicComponents = [
defaultValue: '',
readonly: false,
hiddenLabel: false,
required: false,
},
},
];
Expand Down Expand Up @@ -488,7 +507,6 @@ export const advanceComponents = [
},
},
];

export const layoutComponents = [
{
type: 'grid',
Expand Down Expand Up @@ -659,3 +677,6 @@ export const elementComponentConfig = {
],
},
};

// 表单类组件枚举
export const formElement = ['input', 'textarea', 'number', 'radio', 'checkbox', 'date', 'date', 'rate', 'color', 'select', 'switch', 'slider', 'cascader', 'treeselect', 'richtext'];

0 comments on commit 0d615ab

Please sign in to comment.