组件代码:
<!-- * @Descripttion:表单组件--> <template> <div class='YxkForm'> <el-form :model="form" :ref="$attrs.formRef || 'ruleForm'" v-bind="formBind(formObj)"> <!-- 表单项 --> <el-form-item v-for="(item, index) in formObj.list" :key="index" v-bind="formItemBind(item)"> <FormItem :form="form" :params="item" :selectOptions="selectOptions"> <template v-slot:[item.slots]="scope"> <slot :name="item.slots" :scope="{...scope, $index: index}"></slot> </template> </FormItem> <!-- 提示 --> <template> <div v-if="item.attrs && item.attrs.tip" class="color__danger">{{item.attrs.tip}}</div> </template> </el-form-item> <!-- 表单按钮 --> <template v-if="!formObj.hideButton"> <el-form-item> <FormButton v-for="item in formObj.button" :key="item.text" :params="item"> <template v-slot:text="scope">{{scope.text}}</template> </FormButton> </el-form-item> </template> </el-form> </div> </template> <script> // render渲染 const FormItem = { props: { form: { type: Object }, params: { type: Object }, selectOptions: { type: Object } }, render(createElement) { // 选择项 const options = (params, list) => { // 属性 let item = JSON.parse(JSON.stringify(list)) let props = { attrs: { ...item }, domProps: {}, children: [] } // 属性key值 if (params.keys) { for (let key in params.keys) { props.attrs[key] = item[params.keys[key]] if (key == 'text') { item.text = item[params.keys[key]] } } } this.selectOptions.list.map(list => { if (params.ele == list.ele) props.ele = list.child // 选择项-元素 if (this.selectOptions.type.indexOf(params.ele) != -1) { // 选择项-文本 props.children = [{ ele: 'span', domProps: { innerHTML: item.text } }] } }) // 删除附属属性 if (item.id !== undefined) delete props.attrs.id if (item.text) delete props.attrs.text return createNode(props) } const createNode = params => { // ele 元素 let ele = params.ele // 参数 let props = { attrs: { ...params.attrs }, class: params.class, style: params.style, domProps: { ...params.domProps }, on: {} } // v-model绑定 if (params.model && !params.slots) { props.attrs.value = this.form[params.model] props.on = { input: e => { this.$set(this.form, params.model, e) } } } // 事件 if (params.on) { Object.assign(props.on, params.on) } // 子元素 let childNodes = [] if (params.children) { childNodes = params.children.map(item => { return createNode(item) }) } if (params.options) { // 子元素-选择项 childNodes = params.options.map(item => { return options(params, item) }) } // slot if (params.slots) { childNodes.push(this.$scopedSlots[params.slots](params)) } return createElement(ele, props, childNodes) } return createNode(this.params) }, } // 按钮 const FormButton = { props: { params: { type: Object } }, render(createElement) { const createNode = params => { // ele 元素 let ele = params.ele || 'el-button' // 属性 let attrs = JSON.parse(JSON.stringify(params)) if (attrs.text) delete attrs.text if (attrs.click) delete attrs.click let props = { attrs: { ...attrs }, on: {} } // 事件 if (params.click) { props.on.click = params.click } // 子元素 let childNodes = [] childNodes.push(this.$scopedSlots.text(params)) return createElement(ele, props, childNodes) } return createNode(this.params) }, } export default { name: 'YxkForms', componentName: 'YxkForms', props: { formObj: { type: Object, default: () => { return { button: [] } } }, form: { type: Object } }, components: { FormItem, FormButton }, data() { return { selectOptions: {} } }, methods: { // v-bind formBind(obj) { if (!obj.button) { this.formObj.button = [{ text: '保存', type: "primary", click: () => this.submit() }] } return Object.assign({ size: "medium", 'label-width': '120px' }, this.$attrs) }, formItemBind(obj) { return Object.assign({ prop: obj.model }, this.deleteParams(obj, ['ele', 'model', 'attrs', 'domProps', 'slots', 'children'])) }, // delete params deleteParams(obj, arr) { let params = JSON.parse(JSON.stringify(obj)) arr.forEach(item => { delete params[item] }) return params }, // 默认提交 submit() { this.$emit('submit') }, // 初始化 initialSet() { this.selectOptions = { list: [{ // 选择项 ele: 'el-radio-group', child: 'el-radio' }, { ele: 'el-checkbox-group', child: 'el-checkbox' }, { ele: 'el-select', child: 'el-option' }], type: ['el-radio-group', 'el-checkbox-group'] // 特殊处理选择项 } } }, computed: {}, watch: {}, created() { this.initialSet() }, mounted() {} } </script> <style lang='scss'> .YxkForm { padding: 20px; background: #fff; .color__danger { color: red; font-size: 12px; } } </style>
示例:
参数说明:
YxkForms
formObj
formObj.list
formObj.button