<template> <el-form ref="form" :model="form" inline-message :disabled="options.disabled" :label-position="options.labelPosition || 'left'" :label-width="(options.labelWidth || 100) + 'px'" :size="size" :style="formStyle" class="avue-form-self" @submit.native.prevent="handleConfirm()" > <template v-if="options.column && options.column.length > 0"> <form-content ref="form-content" :form="form" :columns="{ column: options.column }" :options="options" :is-show-important="isShowImportant" ></form-content> </template> <template v-if="options.group && options.group.length > 0"> <!-- <el-tabs v-if="options.tabs" v-model="activeName" type="card"> <el-tab-pane v-for="(g, gIndex) in options.group" :key="gIndex" :label="g.label || `标签${gIndex + 1}`" :name="`${gIndex}`" > <form-content ref="form-content" :form="form" :columns="g" :options="options" :is-show-important="isShowImportant" ></form-content> </el-tab-pane> </el-tabs>--> <!-- 表单的折叠组件 --> <el-collapse v-model="collapseNames"> <template v-for="(g, gIndex) in options.group"> <el-collapse-item v-show="g.display" :key="gIndex" :name="g.prop" :disabled="!g.arrow" :class="g.prop == '1669858313508_15760' ? 'otherItemClass' : ''" > <template slot="title"> {{ g.label }} <span v-if="g.label == '二、排除标准'" class="noCol"> {{ errorText }} </span> </template> <form-content v-if="collapseNames.includes(g.prop)" ref="form-content" :form="form" :columns="g" :options="options" :is-show-important="isShowImportant" :showIndex="g.showIndex" :class="g.showIndex ? 'simple-form' : 'index-form'" ></form-content> </el-collapse-item> </template> </el-collapse> </template> <!-- <div class="form-footer"> <template v-if="options.menuBtn"> <template v-if="options.submitBtn"> <el-button type="primary" :icon="options.submitText == '提交' ? 'el-icon-check' : ''" :loading="loading" size="large" :disabled="disabled" @click="handleConfirm" >{{ options.submitText || "提交" }}</el-button> </template> <template v-if="options.emptyBtn"> <el-button plain icon="el-icon-delete " size="large" @click="resetForm(true)" >{{ options.emptyText || "清空" }}</el-button> </template> </template> <template v-if="nextTabBtnShow"> <el-form style="display: inline-block; margin-left: 10px"> <el-button plain icon="el-icon-caret-right" size="large" @click="nextTab" >{{ options.nextTabText || "下一页" }}</el-button> </el-form> </template> </div>--> </el-form> </template> <script> /** * @description 自定义表单 */ import FormContent from "./FormContent2" import { isObject } from "@/utils/validate" export default { name: "CustomForm", components: { FormContent }, props: { options: { //配置 数据 type: Object, default: () => { return {} }, }, size: { type: String, default: "small" }, formStyle: { type: Object }, formEdit: { type: Object, default: () => { return {} }, }, }, provide() { const vwForm = {} for (const k in this.options) { if (k !== "column" && k !== "group") { vwForm[k] = this.options[k] } } return { vwForm, } }, data() { return { collapseNames: [], activeName: "0", loading: false, isShowImportant: false, form: {}, errorText: "", disabled: false, } }, computed: { nextTabBtnShow() { const { nextTabBtn, tabs, group } = this.options return tabs && group && group.length > 1 && nextTabBtn }, }, watch: { formEdit: { handler() { this.initfields(this.formEdit) }, }, }, created() { this.initforms() this.$nextTick(() => { // this.setformWatch(this.options, "form") }) }, methods: { nextTab() { const tabsLen = this.options.group.length let active = Number(this.activeName) let next = ++active if (next >= tabsLen) next = 0 this.activeName = String(next) this.$emit("scrollTop") }, imFieldChange(val = false) { this.isShowImportant = val }, // 查询 submit() { this.$emit("submit", this.form) }, // 重置 resetForm(flag) { if (flag) { this.$confirm("是否清空数据?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(() => { this.$message({ type: "success", message: "清空成功!", }) this.$refs.form.resetFields() }) .catch(() => {}) } else { if (this.$refs.form) this.$refs.form.resetFields() } }, validate(func) { this.$refs.form.validate((valid) => { func(valid, () => {}) }) }, handleConfirm() { this.loading = true this.$refs.form.validate((valid) => { if (valid) { const data = {} const form = this.deepClone(this.form) Object.keys(form).forEach((k) => { if (form[k] === undefined) { data[k] = "" return false } if (k === "YZZKJC") { // 牙周表格 data[k] = JSON.stringify(form[k]) } else if ( Array.isArray(form[k]) && form[k][0] && isObject(form[k][0]) ) { // 子表单 去除前端添加的显隐辅助数据($_)和 删除按钮辅助数据(showDelBtn) data[k] = form[k].map((item) => { for (let key in item) { if (["$_keyField", "$_hidden", "showDelBtn"].includes(key)) delete item[key] } return item }) } else { data[k] = form[k] } }) this.$emit("handleConfirm", data, () => { this.loading = false }) } else { this.loading = false } }) }, // 表单赋值 initforms() { const form = {} const collapseNames = [] const initFunc = (column = []) => { if (column.length > 0) { column.forEach((item) => { if (!item.prop) return false if ( item.type === "dynamic" || item.type === "checkbox" || item.type === "cascader" || item.type === "upload" || (item.type === "select" && item.multiple) ) { form[item.prop] = [] } else if ( item.type === "dental-tab" || item.type === "dental-tab-tj" ) { form[item.prop] = {} } else if (item.type === "group") { initFunc(item.children.column) } else if (item.type !== "title") { form[item.prop] = item.value ? item.value : "" } }) } } const { group, column } = this.options initFunc(column) group && group.forEach((g) => { if (g.collapse) { collapseNames.push(g.prop) } initFunc(g.column) }) this.collapseNames = collapseNames this.form = form this.loading = false this.$nextTick(() => { // 子组件数据初始化完成后 // setTimeout(() => { this.initfields(this.formEdit) // }, 0) if (this.$refs.form && this.$refs.form.clearValidate) { this.$refs.form.clearValidate() } this.$forceUpdate() }) }, // 绑定部分值(此时表单已渲染) initfields(obj) { console.log("通用表单",obj) for (let k in obj) { // if (this.form.hasOwnProperty(k)) { this.form[k] = obj[k] // } } }, }, } </script> <style lang="scss" scoped> .avue-form-self { padding: 0 11px; ::v-deep .el-collapse { border: none; .el-collapse-item { &:nth-child(1) { border-top: 1px solid #cccccc; } } .el-collapse-item__content { padding-bottom: 0px; } .el-collapse-item__header { background: #fafafa; padding-left: 20px; border: 1px solid #cccccc; border-bottom-color: #ccc; border-top: 0px; font-size: 14px; font-family: AlibabaPuHuiTiM; color: #333333; } .el-collapse-item__wrap { border: none; padding: 10px; // border-left: 1px solid #cccccc; // border-right: 1px solid #cccccc; // border-bottom: 1px solid #cccccc !important; padding: 0px; &:hover { // background-color: #ecf8ff; // outline: 1px dashed #ccc; } } .el-collapse-item__header { font-size: 16px; font-weight: 600; color: rgba(0, 0, 0, 0.85); height: 50px; line-height: 50px; } } .form-footer { margin-top: 20px; text-align: center; } } ::v-deep .el-col { } ::v-deep .el-radio__input.is-disabled .el-radio__inner { // background-color: $base-color-default; // border-color: $base-color-default; } .noCol { font-size: 12px; font-family: AlibabaPuHuiTiR; color: #ff4d4f; } .otherItemClass { ::v-deep { .row24:not(:last-child) { border-left: 0px; } .row24:last-child { border-left: 1px solid #cccccc; } } } .index-form { ::v-deep { // .el-form-item { .el-form-item__label { text-align: left; background: #fafafa; font-size: 14px; color: #333333; border-right: 1px solid #cccccc; width: 80px !important; padding: 18px 10px; margin-right: 20px; text-align: center; } } // } } .simple-form { ::v-deep { .el-form-item__label { margin-left: 20px; } } } </style>