需求

el-table一个格子里面鼠标移上去会出现编辑的按钮,点击的时候格子直接变成input,修改完了直接刷新表格。

思路

用flex布局,分成左边内容右边icon,icon用v-show确定是否展示,值来自el-table的cell-mouse-enter和cell-mouse-leave判断得到的当前所在格子。
给icon绑定点击事件,被点击后,这里用 v-if 判断的 editable 变为 true,使被点击的格子变成el-input。传入当前格子的参数和数据,把数据绑定到input上,同时固定焦点,然后在更新完之后,失去焦点后,发送修改请求同时刷新表格。过程中遇到了以下的问题。

问题1:

表格不能更新
原因:这里控制输入的 editable 字段不是表格原有的属性,也不是表格赋值时就存在的字段。所以在 Vue 实例创建时,以及表格赋值时 editable 并未声明,因此就没有被Vue转换为响应式的属性,自然就不会触发视图的更新。

解决方法:给表格绑定一个key,每次操作修改key,可以触发 table 的重新渲染,这样就可以把修改后的 data 在表格里面更新渲染。

<el-table :key="randomKey">
<el-table/>
refreshTable () {
this.randomKey = Math.random()
},

问题2:

按照上个方法解决,如果给table 添加一个默认高度,这个时候数据比较多的话会出现滚动条;当滚动条拉到下面,点击图标让对应的输入框可编辑,同时触发 table 渲染,滚动条会回到顶部,想查看被操作的输入框需要重新把滚动条拉到最下面;这样体验非常不好。所以这里建议用$set,也是我最后用的解决方法。

fixTextClick (index, row, column) {
row.editable = true
this.nowSelectText = row.text
this.$set(this.tableData, index, row)
this.$refs[column.property].focus()
},

问题3:

修改解决了,但是页面并不会聚焦,这是因为data改变后vue是异步响应的,它会先执行下一条代码,但是这时的el-input并没有显示在页面上,所以不会focus。所以这里需要用到nexttick,最后的代码是:

fixTextClick (index, row, column) {
row.editable = true
this.nowSelectText = row.text
this.$set(this.tableData, index, row)
this.$nextTick(() => {
this.$refs[column.property] && this.$refs[column.property].focus()
})
},

参考链接

elementUI 的 table 表格改变数据不更新问题
vue踩坑日记–input框的focus问题
el-table表格数据变化,页面不更新问题