Vue-表单组件
组件代码:
<!--
* @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

浙公网安备 33010602011771号