最近在重构一个页面,需要把表格做成可编辑的。但是不巧的是Element框架里是没有可编辑表格的,所以只好自己来实现一个了。
实现起来不难,下面我给大家分享一下我是怎么做的。
表格怎么实现可编辑
其实思路很简单,主要利用普通显示和输入框之间的切换,来实现表格的编辑。
1 | <template slot-scope="scope"> |
比如像上面的代码这样,我们使用v-if(或v-show)指令来实现普通的显示和输入之间的切换。
这里使用到了slot-scope,这主要是用于把el-table-column的值传递到input里。
监听表格的点击
首先第一步肯定是去监听点击事件,看看点击了表格的哪里,我好切换输入框。
我本来是想在span上面绑定click的处理的,但是我发现el-table有一个cell-click的事件更加好用!
cell-click | 当某个单元格被点击时会触发该事 | row, column, cell, event |
---|---|---|
cell-click事件有row,column,cell这三个参数,我们可以凭这3个参数来判断现在被点击的是哪一行哪一列的表格。
1 | <el-table :data="list" @cell-click="edit"> |
比如这样,当表格某个格子被点击的时候,我们就调用edit函数,可以在edit函数中进行处理,来切换输入框等。
怎么实现表格的文本与输入框的切换
现在我们知道,使用cell-click时间来监听表格的点击,在edit函数中实现文本与输入框的切换。
一开始的时候,我是想给表格的每一列都加一个对应的状态,比如isEditing1,isEditing2…用第一列v-if可以绑定row.isEditing1,我只要改变这个isEditing1的值为true或false,就可以控制切换了。像下面这样:
1 | <template slot-scope="scope"> |
但是这样的话还要加上那么多个状态,多少列数据就加多少个状态,太麻烦了,这个方案想了一下就被我放弃了。
后来我发现column里面有一个property属性,这个属性其实是数据的变量名。比如上面代码中,column.property = “name”。我只要加一个变量,存储被编辑的数据的变量名即可。当然column还有其他属性可以选择~
1 | <template slot-scope="scope"> |
我给每一行数据加了一个属性editingColumn,顾名思义,是用来指明现在被编辑的是哪一列的数据。我只要在cell-click绑定的edit函数里,修改这个row.editingColumn即可:
1 | edit: function(row, column, cell, event){ |
而且不用担心这一整列数据都会变成输入框,因为我们是根据row参数来修改的,只是改了被点击的这一行的数据。所以只有这一行这一列的格子会变成输入框~
修改之后提交到后台保存
这是需求方提的需求,每修改一个数据就要刷新一次整个表格的数据。
我采用了2种方法:
- @blur失去焦点事件。当输入完成后,用户点击一下其他地方,输入框失去焦点后,就把输入框切换成文本,然后把数据提交到后台。
- 监听回车键@keyup.enter,如果输入完后用户点击了回车键,就把输入框切换成文本,然后把数据提交到后台。
输入框切换成文本跟文本切换成输入框一样,修改editingColumn的值即可。
后来我优化了一下,当数据被修改后再提交到后台,免得没修改也提交,浪费资源,影响体验。
获取焦点的问题
其实还有一个挺影响用户体验的问题,就是你把文本切换成输入框之后,这时候的输入框还是blur的,你还需要再点击一下,才能开始输入。
所以我们的目标也很明确了,就是要切换到输入框之后,马上给输入框获得焦点。
我们可以用vue的自定义指令来实现,大家可以看一下自定义指令的demo——
v-focus,刚好自定义指令的demo就是做了聚焦的例子。
1 | directives: { |
你在input标签加上v-focus属性,即可在被插入到DOM的时候获取到聚焦了。
研究了一个下午的,做出来我感觉体验还挺好的哈哈哈~