需求:点击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 在表格里面更新渲染。