使用
elementUi
的插槽功能,给新增的数据添加自定义属性来实现文本与输入框之间的交互。编辑的时候会有一点特殊需要处理,注意vue
的数据监听原理。
<div>
<el-button type="primary" plain @click.stop="add">新增el-button>
<el-table :data="tableData" style="width: 100%; margin-top: 17px" border>
<el-table-column type="selection" width="55"> el-table-column>
<el-table-column prop="id" label="id"> el-table-column>
<el-table-column label="姓名">
<template slot-scope="{ row }">
<el-input v-if="row.$isEdit" v-model="row.name" placeholder="请输入名字">el-input>
<span v-else>{{ row.name }}span>
template>
el-table-column>
<el-table-column label="地址">
<template slot-scope="{ row }">
<el-input v-if="row.$isEdit" v-model="row.address" placeholder="请输入地址">el-input>
<span v-else>{{ row.address }}span>
template>
el-table-column>
<el-table-column prop="date" label="日期"> el-table-column>
<el-table-column prop="date" label="操作">
<template slot-scope="{ row, $index }">
<el-button type="danger" plain size="mini" @click="deleteData(row, $index)">删除el-button>
<el-button v-if="row.$isEdit" type="primary" plain size="mini" @click.stop="confirmSubmit(row)">确认el-button>
<el-button v-else type="primary" plain size="mini" @click.stop="edit($index)">编辑el-button>
template>
el-table-column>
el-table>
div>
☺☺☺☺☺☺☺
此功能的实现需要使用
vue
里面的v-if
指令,首先在单元格中定义显示内容的标签,再定义一个输入标签,通过按钮改变这两个标签的显示与隐藏来实现单元格可输入功能,注意:这两个标签同时需要绑定对应的值变量。
export default {
data() {
return {
tableData: [
{
id: "1",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
date: "2016-05-02",
},
{
id: "2",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
date: "2016-05-04",
},
{
id: "3",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
date: "2016-05-01",
},
{
id: "4",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
date: "2016-05-03",
},
],
};
},
methods: {
edit(i) {
// 方案一
// 当数据嵌套的时候可以使用
// 需要需要注意
// 必须保证每一条数据在一开始的时候就存在对应字段
// 可以在数据请求回来后先添加对应字段再渲染
// 否则vue监听不到新加入的字段
// 也就不能实现页面交互效果
// row.$isEdit = true;
// 方案二
// 如果数据有嵌套
// 不推荐使用
this.$set(this.tableData[i], "$isEdit", true);
},
// 确认提交
// 发送给后端
// 此demo没有后端
confirmSubmit(row) {
if (!row.name || !row.address) return this.$message.error("不能为空");
let times = new Date(),
formatObj = {
y: times.getFullYear(),
m: times.getMonth() + 1,
d: times.getDate(),
h: times.getHours(),
i: times.getMinutes(),
s: times.getSeconds(),
a: times.getDay(),
};
for (const key in formatObj) {
if (Object.hasOwnProperty.call(formatObj, key)) {
let val = formatObj[key];
if (val < 10 && key !== "a") val = "0" + val;
if (key === "a") val = ["日", "一", "二", "三", "四", "五", "六"][val];
formatObj[key] = val.toString();
}
}
let { y, m, d, h, i, s, a } = formatObj;
row.id = row.id ? row.id : String(times.getTime());
row.address = row.address;
row.date = row.date ? row.date : `${y}-${m}-${d} ${h}:${i}:${s} 星期${a}`;
row.$isEdit = !row.$isEdit;
},
// 删除数据
// 分前端和请求接口删除
deleteData(row, i) {
if (row.$isEdit) {
this.tableData.splice(i, 1);
} else {
console.log("向后端发请求");
}
},
// 新增输入框数据字段
add() {
this.tableData.unshift({
id: "",
name: "",
address: "",
date: "",
$isEdit: true,
});
},
},
};
此
demo
没有后端,所以删除只能是没有提交前的操作,提交后的删除请求的是后端接口。方案一需要通过循环后端返回的列表数据添加添加指定字段来控制输入框的显示与隐藏。方案二就需要在点击按钮的时候传递对应的index
来实现$set
方法,方案二不适用与多层嵌套的数据结构。