1.需求是什么 我的需求是在父组件点击编辑按钮,打开对话框,对话框中有一个table表格嵌套form表单进行特定列的非空校验,列可能是select,input,timePIcker,input等等,这个子组件多处需要使用到,所以需要把这个子组件进行封装,父组件只需要传递columns,dataSouces给子组件即可,下面是代码,大家可以根据自己需求,自行改动
贴上代码
<template>
<div id="app">
<el-form
:model="form"
:rules="rules"
ref="form"
>
<el-table
:data="form.datas"
highlight-current-row
style="width: 100%"
>
<!-- 排序列 -->
<el-table-column
prop="id"
label="序号"
width="60"
></el-table-column>
<el-table-column
:prop="item.dataIndex"
v-for="(item, index) in columns"
:key="index"
:label="item.lable"
>
<template slot-scope="scope">
<template>
<el-form-item
:prop="'datas.' + scope.$index + '.' + item.dataIndex"
:rules="rules[item.dataIndex]"
>
<el-input
v-if="item.type === 'input'"
size="mini"
v-model.trim="scope.row[item.dataIndex]"
style="width: 120px"
></el-input>
<el-select
v-if="item.type === 'select'"
v-model="scope.row[item.dataIndex]"
placeholder="请选择"
>
<el-option
v-for="item1 in item.option"
:key="item1.value"
:label="item1.label"
:value="item1.value"
></el-option>
</el-select>
</el-form-item>
</template>
</template>
</el-table-column>
prop="options"
label="晚餐"
>
<template slot-scope="scope">
<template>
<el-form-item
:prop="'datas.' + scope.$index + '.options'"
:rules="rules.options"
>
<el-select
v-model="scope.row.options"
placeholder="请选择"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</template>
</template>
</el-table-column>
<el-table-column
prop="operation"
label="操作"
>
<template slot-scope="scope">
<template v-if="scope.row.action == 'view'">
<el-button
size="mini"
@click="click_edit(scope.row, scope.$index)"
>
编辑
</el-button>
<el-button
size="mini"
@click="click_delete(scope.row, scope.$index)"
>
删除
</el-button>
</template>
<template v-else-if="scope.row.action == 'add'">
<el-button
size="mini"
@click="click_add(scope.row, scope.$index)"
>
新增
</el-button>
<el-button
size="mini"
@click="click_reset(scope.row, scope.$index)"
>
重置
</el-button>
</template>
<template v-else>
<el-button
size="mini"
@click="click_save(scope.row, scope.$index)"
>
保存
</el-button>
<el-button
size="mini"
@click="click_cancle(scope.row, scope.$index)"
>
取消
</el-button>
</template>
</template>
</el-table-column> -->
</el-table>
</el-form>
</div>
</template>
<script>
const option = [
{
value: '选项1',
label: '黄金糕'
},
{
value: '选项2',
label: '双皮奶'
},
{
value: '选项3',
label: '蚵仔煎'
},
{
value: '选项4',
label: '龙须面'
},
{
value: '选项5',
label: '北京烤鸭'
}
]
const validatePass = (rule, value, callback) => {
if (!Number.isInteger(Number(value))) {
console.log(typeof value)
return callback(new Error('请输入数字值'))
} else {
callback()
}
}
export default {
watch: {
form: {
handler(value) {
console.log(value, 'value')
},
deep: true
}
},
data() {
return {
form: {
datas: [
{
id: 0,
name: '张三',
age: 20,
option: ''
},
{
id: 1,
name: '李四',
age: 32,
option: ''
}
]
},
columns: [
{
type: 'input',
dataIndex: 'name',
width: '',
lable: '姓名'
},
{
type: 'input',
dataIndex: 'age',
width: '',
lable: '年纪'
},
{
type: 'select',
dataIndex: 'option',
option,
width: '',
lable: '晚餐'
}
],
//表单验证规则
rules: {
name: [
{
type: 'string',
required: true,
trigger: 'blur',
message: '请输入姓名'
}
],
age: [
{
// type: 'number',
required: true,
trigger: 'blur',
message: '请输入年龄'
},
{ validator: validatePass, trigger: 'blur' }
// {
// type: 'number',
// trigger: 'blur',
// min: 0,
// max: 120,
// message: '年龄最小0,最大120'
// }
],
options: [
{
type: 'string',
required: true,
trigger: 'change',
message: '请输入晚餐'
}
]
}
}
},
created() {
//处理数据,为已有数据添加action:'view'
this.form.datas.map((item) => {
this.$set(item, 'action', 'view')
return item
})
},
methods: {
//对部分表单字段进行校验
validateField(form, index) {
let result = true
for (let item of this.$refs[form].fields) {
if (item.prop.split('.')[1] == index) {
this.$refs[form].validateField(item.prop, (error) => {
if (error != '') {
result = false
}
})
}
if (!result) break
}
return result
},
//对部分表单字段进行重置
resetField(form, index) {
this.$refs[form].fields.forEach((item) => {
if (item.prop.split('.')[1] == index) {
item.resetField()
}
})
},
//新增操作
click_add(item, index) {
if (!this.validateField('form', index)) return
//模拟新增一条数据
let itemClone = JSON.parse(JSON.stringify(item))
itemClone.id = this.form.datas.length
itemClone.action = 'view'
this.form.datas.push(itemClone)
this.resetField('form', index)
},
//新增-重置操作
click_reset(item, index) {
this.resetField('form', index)
},
//编辑-保存操作
click_save(item, index) {
if (!this.validateField('form', index)) return
item.action = 'view'
},
//编辑-取消操作
click_cancle(item, index) {
this.resetField('form', index)
item.action = 'view'
},
//编辑操作
click_edit(item, index) {
item.action = 'edit'
},
//删除操作
click_delete(item, index) {
this.$confirm('确定删除该条数据(ID' + item.id + ')吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
//模拟删除一条数据
this.form.datas.splice(index, 1)
})
.catch(() => {})
}
}
}
</script>
<style>
.el-table .cell {
overflow: visible;
}
.el-form-item {
margin-bottom: 0;
}
.el-form-item__error {
padding-top: 0;
margin-top: -3px;
}
</style>