技术栈:vue2+ js + webpack
需求:
利用数据渲染表单,实现代码的精简化及效率的提升。
效果图:
封装的组件:
<div v-if="formConfig"><el-formv-bind="$attrs"ref="formDom":model="formData":rules="formRules":inline="inline":label-width="labelWidth":label-position="labelPosition"><el-form-itemv-for="(item, key, index) in formConfig":key="key":label="item.label":label-width="item.labelWidth || '61px'":prop="key":style="item.style"v-if="!item.hide"><!-- 只列出focus blur change事件举例,更多事件可以自行添加绑定 --><el-inputv-bind="$attrs"v-if="item.type === 'input'"v-model="formData[key]":disabled="item.disabled":type="item.inputType ? item.inputType : 'text'":placeholder="item.placeholder || `请输入${item.label}`"clearable@focus="e => issueEvent(e, item.onFocus)"@blur="e => issueEvent(e, item.onBlur)"@change="e => issueEvent(e, item.onChange)"/><el-selectv-if="item.type === 'select'"v-model="formData[key]"clearable:disabled="item.disabled":placeholder="item.placeholder || `请选择${item.label}`":multiple="item.multiple":filterable="item.filterable":max-tag-count="item.max_tag_count"style="width:100%"@change="e => issueEvent(e, item.onChange)"><el-optionv-for="list in item.options":key="list.value":value="list.value":label="list.label"></el-option></el-select><el-cascaderv-if="item.type === 'cascader'"v-model="formData[key]":disabled="item.disabled":options="item.options":show-all-levels="false"style="width:100%":placeholder="item.placeholder || `请输入${item.label}`":props="item.props"@change="e => issueEvent(e, item.onChange)"></el-cascader><el-date-pickerv-if="item.type === 'dateTime'"v-model="formData[key]":picker-options="pickerOptions":type="item.dateType ? item.dateType : 'month'":key="item.dateType ? item.dateType : 'month'":placeholder="item.placeholder || `请选择${item.label}`":value-format="item.format"></el-date-picker><slot name="form" :item="item" :from="formData[key]" /><div><el-buttonv-if="item.type === 'confirm'"type="primary"icon="el-icon-search":loading="item.isSearching"@click="submit">{{ item.text ? item.text : "查询" }}</el-button><el-buttonv-if="item.type === 'reset'"icon="el-icon-refresh"@click="reset">{{ item.text ? item.text : "重置" }}</el-button><el-buttonv-if="item.type === 'export'"class="downloadbtn"@click="handleExport"><svg-icon icon-class="ic_export" class="tablesvgicon"></svg-icon>{{ item.text ? item.text : "导出" }}</el-button><slot name="button" :item="item" /></div></el-form-item></el-form></div>
</template><script>
export default {name: "customForm",props: {// 表单项是否行内显示inline: {type: Boolean,default: true},// 表单项配置formConfig: {type: Object,default: () => {}},// 表单项数据formDataInit: {type: Object,default: () => {}},// 表单标签宽度labelWidth: {type: [Number, String],default: "61"},// 表单标签位置,默认左侧labelPosition: {type: String,default: "left"},// 表单校验规则formRules: {type: Object,default: () => {}}},data() {return {formData: this.formDataInit};},methods: {//重点在issueEvent函数,可以给事件绑定一个空函数避免报错,如果有外部传入的自定义函数则返回这个函数/*组件内函数负责分发表单项事件 */issueEvent(value, mouseEvent) {if (mouseEvent) {return mouseEvent(value);}},submit() {this.$emit("submit");},reset() {this.$refs.formDom.resetFields();this.$emit("reset");},handleExport() {this.$emit("handleExport");}}
};
</script><style lang="scss" scoped>
/deep/ .el-cascader--medium {line-height: 28px;
}
</style>
组件的运用:
<template><div><div class="search-box xl-querybox marginbottom15 borderRadius1 "><!-- 这里是测试页 测试引入组件 --><BaseFrom:formDataInit="formDataInit":form-config="formConfig":form-rules="formRules"@submit="getList"><template #form="{from,item}"><div v-if="item.type === 'tab'"><el-radio-group v-model="from" @change="handleQuery($event, from)"><el-radio-button :label="1">日</el-radio-button><el-radio-button :label="2">月</el-radio-button><el-radio-button :label="3">年</el-radio-button></el-radio-group></div></template><template #button="{item}"><div v-if="item.type === 'button'">12313</div></template></BaseFrom><!-- 新增编辑的表单 --></div><div class="edit-from-style"><BaseFrom:formDataInit="formDataInit":form-config="formConfig2":form-rules="formRules":inline="false"@submit="getList"></BaseFrom></div></div>
</template><script>
import BaseFrom from "@/components/BaseFrom";
import { formatDate_y_m_d } from "@/utils/index";
export default {components: {BaseFrom},data() {return {formConfig2: {id: {label: "id",type: "input",// style: { width: "20%" },placeholder: "看看提示语",labelWidth: "null"},name: {label: "name",type: "input",placeholder: "看看提示语",labelWidth: "null"},ids: {label: "项目id",type: "cascader",style: { width: "100%" },props: {expandTrigger: "hover",children: "childs",label: "label",value: "value"},options: [{ label: "请选择", value: "" },{ label: "技术", value: "技术" },{ label: "生活", value: "生活" },{ label: "其他", value: "其他" }],labelWidth: "null"}},/*----------表格头部的查询表单---------- */isSearching: false, // // 是否查询中// 表单配置formConfig: {id: {label: "id",type: "input",placeholder: "看看提示语"},ids: {label: "项目id",type: "cascader",props: {expandTrigger: "hover",children: "childs",label: "label",value: "value"},options: [{ label: "请选择", value: "" },{ label: "技术", value: "技术" },{ label: "生活", value: "生活" },{ label: "其他", value: "其他" }]},status: {label: "状态",type: "select",// multiple: true, // 是否支持多选max_tag_count: 1, // 多选时最多显示多少个 tagoptions: [{label: "数据一",value: "0"},{label: "数据二",value: "1"}],onChange: (value, label, arr) => {console.log(value, label, arr);if (value == "0") {this.formConfig["id"].disabled = false;} else {this.formConfig["id"].disabled = true;}console.log("this.formDataInit", this.formDataInit);}},tab: {label: "周期",type: "tab",labelWidth: "10"},time: {label: "时间",type: "dateTime"},// time1: {// label: "时间组2件",// type: "dateTime",// dateType: "year",// format: "yyyy-MM-dd",// labelWidth: "100"// },confirm: {text: "查询", // 按钮文案type: "confirm",label: " ",labelWidth: 0,isSearching: this.isSearching},reset: {type: "reset"},button: {type: "button"}},// 表单数据formDataInit: {id: "",page_number: 1,page_size: 10,time: formatDate_y_m_d(new Date()),tab: 1},// 表单校验规则formRules: {id: [{ required: true, message: "请输入id", trigger: "blur" },{ min: 3, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" }],status: [{ required: true, message: "请选择", trigger: "change" }]}};},methods: {getList() {console.log("提交了", this.formDataInit);},handleQuery($event, from) {this.formDataInit.tab = from;console.log("4444", $event, from);switch (from) {case 3:this.formConfig.time.dateType = "year";this.formConfig.time.format = "yyyy-MM-dd";this.formConfig.time.placeholder = "选择年";break;case 2:this.formConfig.time.dateType = "month";this.formConfig.time.format = "yyyy-MM-dd";this.formConfig.time.placeholder = "选择年月";break;case 1:this.formConfig.time.dateType = "date";this.formConfig.time.format = "yyyy-MM-dd";this.formConfig.time.placeholder = "选择年月日";break;default:break;}}}
};
</script><style lang="scss" scoped>
.edit-from-style {/deep/.el-form {.el-form-item {height: 60px;line-height: 60px;align-items: center;text-align: center;justify-content: flex-start;display: flex;border: 1px solid #ebeef5;@include timeAndChooseColor2();margin-bottom: 0;&:not(:last-child) {border-bottom: none;}}.el-form-item__content {margin-left: 10px !important;width: 40%;@media screen and (max-width: 800px) {width: 66%;}}.el-form-item__label {width: 210px;line-height: 58px;padding-left: 10px;background-color: #fafafa;border-right: 1px solid #ebeef5;&:not(:last-child) {border-bottom: none;}@media screen and (max-width: 800px) {width: 90px;}@include tableBorderColor7();@include formBox();// @include bgColor2();}}
}
</style>
参考文章:添加链接描述