Vue+element - ui 自定义动态表单带校验
// 父组件
<FromTrends @getFromData="getFromData" titleText="添加/编辑" :formData="formData"/>
父组件对应的数据
formData: {
dataName: "",
formItemList: [
{
label: '名称', // lable名称
disabled: false, // 禁止编辑
defaultValue: '', //默认值
itemId: 'dataName', // 绑定的name属性
required: true, // 是否必填
placeholder: '请填写正确的信息', // 默认灰色提示文本
width: 300, // 文本框宽度
type: 'INPUT', // 表单类型
message: '请填写正确的信息', // 如果未填写,提示用户的信息
value: '11', // 绑定的值
defDataList: [] // 如果是select活着tree需要绑定的数组值
},
{
label: 'select', // lable名称
disabled: false, // 禁止编辑
defaultValue: '', //默认值
itemId: 'select222', // 绑定的name属性
required: true, // 是否必填
placeholder: '请选择', // 默认灰色提示文本
width: 300, // 文本框宽度
type: 'SELECT', // 表单类型
filterable: false, // 是否可搜索
multiple: false, // 是否可多选
message: '', // 如果未填写,提示用户的信息
keyLabel: 'label',
keyValue: 'value',
value: '', // 绑定的值 // multiple 为多选的时候这里是数组,
defDataList: [
{
label: '选型1',
value: 1
},
{
label: '选型2',
value: 2
}
]
},
{
format: "YYYY-MM-DD",
label: 'DATE', // lable名称
disabled: false, // 禁止编辑
defaultValue: '', //默认值
itemId: 'DATEDATE', // 绑定的name属性
required: true, // 是否必填
placeholder: '', // 默认灰色提示文本
width: 300, // 文本框宽度
type: 'DATE', // 表单类型
message: '请填写正确的信息', // 如果未填写,提示用户的信息
value: '', // 绑定的值
defDataList: [] // 如果是select活着tree需要绑定的数组值
},
{
label: 'TEXTAREA', // lable名称
disabled: false, // 禁止编辑
defaultValue: '', //默认值
itemId: 'textarea', // 绑定的name属性
required: false, // 是否必填
placeholder: '', // 默认灰色提示文本
width: 300, // 文本框宽度
type: 'TEXTAREA', // 表单类型
message: '请填写正确的信息', // 如果未填写,提示用户的信息
value: '', // 绑定的值
defDataList: [] // 如果是select活着tree需要绑定的数组值
},
{
label: 'AllDATE', // lable名称
type: 'ALLDATE', // 表单类型
message: '请选择日期', // 如果未填写,提示用户的信息
disabled: false, // 禁止编辑
defaultValue: '', //默认值
itemId: 'allDATE', // 绑定的name属性
required: true, // 是否必填
placeholder: '', // 默认灰色提示文本
width: 300, // 文本框宽度
value: ['2012-09-11', '2012-09-18'], // 默认的绑定的区间是个数组
defDataList: [] // 如果是select活着tree需要绑定的数组值
}
]
}
子组件
<template>
<div id="trendsForm">
<el-dialog
:title="titleText?titleText:'标题'"
:visible.sync="dialogVisible"
:before-close="handleClose">
<div>
<!--:rules="rules" -->
<el-form ref="ruleForm" :label-position="labelPosition" label-width="120px"
:model="formData">
<!---->
<div v-for="(item,index) in formData.formItemList" :key="index">
<el-form-item v-if="item.type==='INPUT'" :prop="'formItemList.' + index + '.value'"
:label="item.label"
:rules="[{ required: item.required, message:item.message?item.message:'信息必须填写'}]">
<el-input :placeholder="item.placeholder"
v-model="item.value">
</el-input>
</el-form-item>
<el-form-item v-if="item.type==='TEXTAREA'" :prop="'formItemList.' + index + '.value'"
:label="item.label"
:rules="[{ required: item.required, message:item.message?item.message:'信息必须填写'}]">
<el-input type="textarea" :placeholder="item.placeholder"
v-model="item.value">
</el-input>
</el-form-item>
<el-form-item v-if="item.type==='SELECT'" :label="item.label"
:prop="'formItemList.' + index + '.value'"
:rules="[{ required: item.required, message:item.message?item.message:'请选择'}]">
<el-select :multiple="item.multiple?item.multiple:false" filterable v-model="item.value"
:placeholder="item.placeholder">
<el-option v-for="(v,index) in item.defDataList" :key="index"
:label="item.keyLabel?v[item.keyLabel]:v.label"
:value="item.keyValue?v[item.keyValue]:v.value"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="item.type==='DATE'" :label="item.label"
:prop="'formItemList.' + index + '.value'"
:rules="[{ required: item.required, message:item.message?item.message:'请选择'}]">
<el-date-picker type="date" :placeholder="item.placeholder?item.placeholder:'请选择日期'"
v-model="item.value"
style="width: 100%;"></el-date-picker>
</el-form-item>
<!--多日期选择-->
<el-form-item v-if="item.type==='ALLDATE'" :label="item.label"
:prop="'formItemList.' + index + '.value'"
:rules="[{ required: item.required, message:item.message?item.message:'请选择'}]">
<el-date-picker
v-model="item.value"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</div>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import moment from 'moment';
// 组件传递进来的值
// {
// label: '名称', // lable名称
// disabled: false, // 禁止编辑
// defaultValue: '', //默认值
// itemId: 'dataName', // 绑定的name属性
// require: true, // 是否必填
// placeholder: '', // 默认灰色提示文本
// width: 300, // 文本框宽度
// type: 'INPUT', // 表单类型
// message: '请填写正确的信息', // 如果未填写,提示用户的信息
// value: '', // 绑定的值
// filterable: false, // 是否可搜索(select)
// multiple: false, // 是否可多选(select)
// defDataList: [] // 如果是select活着tree需要绑定的数组值
// }
export default {
name: "FromTrends",
data() {
return {
dialogVisible: true,
labelPosition: 'right'
}
},
props: ['formData', 'titleText'],
components: {},
methods: {
handleClose() {
this.dialogVisible = false
},
confirm() { // confirm 表单
this.submitForm('ruleForm')
},
/**
* 提交表单验证
* @param formName
*/
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// 验证通过
this.$emit('getFromData', this.getFROMData())
} else {
console.log('error submit!!');
return false;
}
});
},
/**
* 数据合法之后获取当前需要的数据
* @param data // this.formData
*/
getFROMData() {
let jsonArr = {}
this.formData.formItemList.map((v) => {
if (v.type === 'DATE') {
v.value ? v.value = moment(v.value).format(v.format ? v.format : 'YYYY-MM-DD') : null
}
if (v.type === 'ALLDATE') {
if (v.value.length > 0) {
let dateString = []
v.value.map((v1) => {
dateString.push(moment(v1).format(v.format ? v.format : 'YYYY-MM-DD'))
})
v.value = dateString
}
}
jsonArr[v.itemId] = v.value ? v.value : ''
})
return jsonArr
},
/**
* 初始化表单
* @param formName
*/
resetForm() {
this.$refs.ruleForm.resetFields();
}
},
mounted() {
}
}
</script>
<style lang="less">
#trendsForm {
.line {
text-align: center;
}
}
</style>
网友评论