使用Vue+Element-UI简单的做了一个表格的增删改,效果图如下,新增和修改编辑共用一个弹框表单组件。
首先点击编辑按钮,把当前的行数据传递给子组件,开始我以为只要在父组件中传递相应的props,然后子组件里获取即可,但是没有表单并没有读取到数据。
// 父组件
<template>
...
<edit-modal
:row="row"
:visible.sync="dialogFormVisible"
@close="dialogFormVisible = false"
@updateItem="onUpdateSubmit"
/>
...
</template>
<script>
...
data() {
return {
row: {}
}
}
...
methods: {
// 编辑按钮
updateItem(row) {
this.row = {...row}
}
...
}
</script>
// 子组件
<template> ... </template>
<script>
...
props: {
row: Object
},
data() {
return {
form: this.row
}
}
...
</script>
分析:在表格页加载完成时,子组件也已经挂载到DOM上,此时this.form = {},所以当点击编辑的时候,并不会像我们想象的那般父组件改变了row的值,然后子组件开始渲染,在data中初始化数据。子组件中的data在beforeCreated和created之间就已经完成。
所以点击编辑按钮,在父组件中修改row的时候,子组件中this.form没有更新,解决方法可以使用v-if,在父组件中控制子组件是否重新渲染,当然每次重新挂载子组件不是一种好方法,也可以使用$nextTick,调用子组件的方法,改变this.form的值。如下:
// 父组件
updateItem(row = {}) {
this.dialogFormVisible = true;
this.$nextTick(() => {
this.$refs.editModal.dataInit(row);
})
},
// 子组件
dataInit(data) {
if (data) {
//初始化表单,清空验证等
this.form = {...data};
this.$refs.form.resetFields();
}
},
完整代码如下:
父组件:
<template>
<div class="about">
<div class="lottery">
<el-button type="primary" @click="updateItem">添加</el-button>
<el-button type="danger" @click="open" :disabled="multipleSelection.length === 0">删除</el-button>
</div>
<el-table
:data="tableData"
border
ref="multipleTable"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection"></el-table-column>
<el-table-column prop="id" label="序号"></el-table-column>
<el-table-column prop="name" label="选项"></el-table-column>
<el-table-column prop="creator" label="创建人"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="updateItem(scope.row)" type="text" size="small">编辑</el-button>
<el-popconfirm
:title="['选项删除后无法恢复,确认删除[' + scope.row.name + ']吗'] + '?'"
@confirm="deleteItem(scope.row)"
>
<el-button slot="reference" type="text" size="small">删除</el-button>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<edit-modal
ref="editModal"
:visible.sync="dialogFormVisible"
@close="dialogFormVisible = false"
@updateItem="onUpdateSubmit"
/>
</div>
</template>
<script>
import editModal from './editModal.vue'
export default {
components: { editModal },
data() {
return {
tableData: [
{
id: 113,
name: 'a',
creator: 'dd',
}
],
multipleSelection: [],
dialogFormVisible: false,
}
},
methods: {
open() {
const content = this.multipleSelection.map(v => v.name)
this.$confirm(`确认删除${content.join(',')}吗`, '批量删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 删除 batchDelete
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
updateItem(row = {}) {
this.dialogFormVisible = true;
this.$nextTick(() => {
// 弹框打开时初始化表单
this.$refs.editModal.dataInit(row);
})
},
onUpdateSubmit(data) {
if (data?.id) {
this.tableData.map(v => v.id === data.id ? v.name = data.name : v.name);
} else {
this.tableData.push({
id: Math.floor(Math.random() * 300),
name: data.name,
creator: 'dd',
})
}
this.dialogFormVisible = false;
},
deleteItem(row) {
this.tableData = this.tableData.filter(v => v.id != row.id);
this.getList();
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
getList() {
this.tableData = [...this.tableData, {
id: Math.floor(Math.random() * 100),
name: 'a',
creator: 'dd',
}]
},
},
mounted() {
this.getList();
}
}
</script>
<style scoped>
.lottery {
text-align: left;
}
.operate {
margin: 15px 0;
}
</style>
子组件:
使用before-close控制弹框的关闭按钮和点击模态框时,调用对应的函数,处理一些数据。
<template>
<el-dialog :title="title" :visible.sync="visible" :before-close="onClose">
<el-form :model="form" :rules="rules" ref="form">
<el-form-item label="选项" prop="name">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="onClose">取 消</el-button>
<el-button type="primary" @click="submit">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
export default {
name: 'editModal',
props: {
visible: false
},
data() {
return {
form: {},
rules: {
name: [
{ required: true, message: '请输入选项' },
],
},
}
},
computed: {
title: function () {
return this.form.id ? '修改' : '添加'
}
},
methods: {
dataInit(data) {
if (data) {
this.form = {...data};
this.$refs.form.resetFields();
}
},
onClose() {
this.$emit('close')
},
submit() {
this.$refs.form.validate((valid) => {
if (valid) {
this.$emit('updateItem', this.form)
} else {
return false;
}
})
}
},
}
</script>