需求:点击table表格中的“修改”之后,当前行变为可输入状态的行,点击“确定”后变为普通表格;
先贴上已经完美解决问题的代码
实现代码:
<section>
<div style="display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px">
<h4>接入点信息</h4>
<el-button type="primary" @click="addBtn">新 增</el-button>
</div>
<el-form ref="form1" :model="formData" label-width="0px" :inline-message="true">
<el-table :data="formData.access_param" :border="true">
<el-table-column label="名称" align="center" prop="name">
<template slot="header">
<span>
<span class="fred">*</span>
名称
</span>
</template>
<template slot-scope="scope">
<el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.name'" :rules="tableFromRules.name">
<el-input v-model="scope.row.name"></el-input>
</el-form-item>
<span v-else>{{ scope.row.name }}</span>
</template>
</el-table-column>
<el-table-column label="拓扑角色" align="center" prop="topo_type">
<template slot="header">
<span>
<span class="fred">*</span>
拓扑角色
</span>
</template>
<template slot-scope="scope">
<el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.topo_type'" :rules="tableFromRules.topo_type">
<el-select v-model="scope.row.topo_type" clearable>
<el-option :value=1 label="任意到任意"></el-option>
<el-option :value=2 label="中心节点"></el-option>
<el-option :value=3 label="边缘节点"></el-option>
<el-option :value=4 label="点到点"></el-option>
</el-select>
</el-form-item>
<span v-else>{{ scope.row.topo_type }}</span>
</template>
</el-table-column>
<el-table-column label="接入方式" align="center" prop="access_type">
<template slot="header">
<span>
<span class="fred">*</span>
接入方式
</span>
</template>
<template slot-scope="scope">
<el-form-item v-if="scope.row.editable" :prop="'access_param.' + scope.$index + '.access_type'" :rules="tableFromRules.access_type">
<el-select v-model="scope.row.access_type" clearable>
<el-option :value=1 label="单归"></el-option>
<el-option :value=2 label="双归主备"></el-option>
<el-option :value=3 label="双归负载"></el-option>
</el-select>
</el-form-item>
<span v-else>{{ scope.row.access_type }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120">
<template slot-scope="scope">
<div class="fullstacktable_btn">
<el-button @click="modifyBtn(scope.row,scope.$index)" type="button" v-show="title == '修改'&&!scope.row.editable">修改</el-button>
<el-button @click="saveBtn(scope.row,scope.$index)" type="button" v-show="title == '修改'&&scope.row.editable">确定</el-button>
<el-button @click="delBtn(scope.row,scope.$index)" type="button">删除</el-button>
</div>
</template>
</el-table-column>
</el-table>
</el-form>
</section>
data中的数据定义部分
formData: {
access_param: [
{ name: "", topo_type: "", access_type: "", status: true, editable: true},
],
},
说明:其中,status字段为接口返回的字段,用来表示是否可以编辑或删除;true表示可以删除或修改,false表示被占用中,不可以删除或修改;editable是前端页面自己定义的字段,用来控制显示可编辑列还是普通列;
methods中的方法实现
addBtn() {
let flag = false;
this.formData.access_param.forEach((item, index) => {
if (!item.name || !item.topo_type || !item.access_type) {
flag = true;
return true
}
})
if (flag) {
this.$message({
message: '请先完善必填信息!',
type: 'info',
showClose: true
});
} else {
this.formData.access_param.push({
name: "",
topo_type: "",
access_type: "",
editable: true,
status: true
})
}
},
modifyBtn(row,index) {
if (!row.status) { // true:可以修改;false:不可以修改;
this.$message({
message: '已被占用,不支持修改!',
type: 'warning',
showClose: true
});
return
}
this.formData.access_param[index].editable = true;
this.formData = JSON.parse(JSON.stringify(this.formData));
},
saveBtn(row,index) {
if (row.name == "" || row.topo_type == "" || row.access_type == "") {
this.$message({
message: '请先完善必填信息!',
type: 'info',
showClose: true
});
return
}
this.formData.access_param[index].editable = false;
this.formData = JSON.parse(JSON.stringify(this.formData));
},
delBtn(row,index) {
if (!row.status) { // true:可以修改;false:不可以修改;
this.$message({
message: '已被占用,不支持删除!',
type: 'warning',
showClose: true
});
return
}
if (this.formData.access_param.length === 1) {
this.$message({
message: '至少保留一条数据',
type: 'warning',
showClose: true
})
return
}
this.formData.access_param.splice(index,1)
},
遇到问题的解决步骤:
-
在modifyBtn方法中想要通过修改当前行的editable字段来切换可编辑行和普通行
this.formData.access_param[index].editable = true;
点击“修改”按钮没有效果,数据更新了视图没有更新,因为数据层次太多,render函数没有自动更新,需手动强制刷新。 -
通过this.$forceUpdate()强制刷页面,依然无效
this.formData.access_param[index].editable = true;
this.$forceUpdate();
- 想要使用this.$set来更新视图
this.$set(this.formData.access_param[index],'editable', true);
结果:第一次点击“修改”按钮可以将当前行变为可编辑的列,但是点击其他的“修改按钮”就没有效果了
- 把当前行的
this.formData.access_param[index].editable = true;
设置为true;然后在把 表格的数据 用this.formData = JSON.parse(JSON.stringify(this.formData));
重新克隆一遍再赋值给表格就OK了,这也是我代码中使用的方法,但是使用JSON.parse(JSON.stringify());
这种方法会有缺陷:如果数据中有使用new Date会将其转换成字符串,需要把数据过滤一下;
this.formData.access_param = this.formData.access_param.filter(item => item);
- 最完美的办法:直接使用es6的 Object.assign复制一个新的对象
this.formData = Object.assign([],this.formData)
简单明了
其他办法:
给table加key
:修改绑定在 table 上面的 key 值,可以触发 table 的重新渲染,这样就可以把修改后的 data 在表格里面更新渲染。