首页 > 其他 > 详细

17.Vue技术栈开发实战-可编辑表格的实现

时间:2020-07-06 01:13:52      阅读:60      评论:0      收藏:0      [点我收藏+]

通过对iview的table表格的封装,实现如何自定义表格的内容。实现一个可编辑的表格。
技术分享图片
为了节省时间,首先已经做了一些准备
首先是已经创建了table页
技术分享图片
然后写了一个api,用来获取表格数据。
技术分享图片
然后在mock里面也进行了处理。返回了数据的响应
技术分享图片
tools里面封装了一个方法doCustomTImes
技术分享图片
times是循环的次数,callback是回调函数。
技术分享图片

执行循环5次,根据template生成5条数据记录。
技术分享图片
最后在table页调用访问api的方法
技术分享图片

可编辑表格组件

创建edit-table组件。
技术分享图片
index.js内,引入并导出组件
技术分享图片
组装封装,只用到iview里面的table组件。外面不用包裹顶层的div直接用Table就可以了。
技术分享图片
有两个需要传的重要的属性,一个是定义列的数组,一个是数据的数组。在table.vue里面我们已经定义好了。 
技术分享图片

key就是绑定的字段值,title就是列的标题。editable是我们自定义的属性,并不是iview的属性。
技术分享图片
引入组件并注册
技术分享图片
组件内定义属性 columns是一个空的数组,数组设置默认值,要写一个回调函数,返回一个空数组。
技术分享图片
技术分享图片
把属性传入Table组件。
技术分享图片

给表格添加可编辑的按钮

要给这个表格添加一个可编辑的按钮。是不是要在columns里面给这个列添加一个render回调函数呢?如果你在这里要自己写的话,是要加一个render,然后传入一个回调函数。
技术分享图片
我们既然要封装一个可编辑表格,那么这个工作肯定是要内部做了。
所以在哪去处理,这里列数组的东西呢?
首先在计算属性里面 我们拿到了列
技术分享图片
在这里我们就要会columns做处理了。在这里定义一个indiseColumns,因为我们不能直接修改父组件传递过来的数据的。如果要修改就必须抛出一个事件,在父组件内接收事件,在事件的绑定回调函数里面去做数据的修改。 
技术分享图片
这里我们用map做映射
技术分享图片
如果传入的列有render函数,说明在外面自定义了render
技术分享图片
只要是没有自带render,并且editable为true的情况下。
技术分享图片
这里是一个解构赋值的形式
技术分享图片
第一个参数是组件名,第二个参数是可配置的属性,第二个参数是可选的。
技术分享图片
如果没有需要可设置的值,就把它删掉。
技术分享图片
第三个参数是当前这个节点的子节点,如果里面就写一个字符串。它渲染出来的就是包含这个字符串的div
技术分享图片

如果你是一个组件,第三个参数就是一个数组,比如我们渲染之前封装的CountTo组件,然后后面定义相关的属性。
第三个参数一定是一个数组或者是字符串。这是render函数的写法。
技术分享图片

jsx

为了简介简便,我们用jsx的写法。直接返回一个括号,在括号里面要渲染我们的标签。
技术分享图片
这里必须有一个最外层的div包裹。任何东西都包在这个div里面。
技术分享图片

点击这里就编程一个输入框。点击保存输入框小时,文字显示了。这里应该是一个v-if和v-else的逻辑
技术分享图片 
但是在jsx里面我们没法用v-if这些指令。所以我们要通过js去判断这个逻辑。我们的逻辑和变量都要用花括号来包裹。
技术分享图片
先点击第一行编辑  第一个22就编程输入框,再点击20的数字,20这里编程输入框。同时只能编辑一个单元格。那么我可以给每个单元格一个标志。当我点击某个单元格的编辑按钮的时候,让那个全局的值,变成党员个格的值,通过这个全局的标志来判断当前哪个单元格应该显示输入框。
技术分享图片
定义全局的变量。这个edittingId,表格里面每一行都有一个行号。每一列都有一个key值。我们通过行号和key值就能确定单元格。我们的这个edittingId就是行号和key拼接起来,就能代表一个单元格。
技术分享图片
先把这三个值打印出来,看一下
技术分享图片
表格里最后用的是insideColumns
技术分享图片

技术分享图片
需要定义这个变量
技术分享图片

技术分享图片

技术分享图片
打印出来的值。
技术分享图片
第三个值
技术分享图片
这样就获取到这一列的单元格
技术分享图片
接下来要加一个按钮,iview的组件呢在jsx里面 要用i-的形式。
技术分享图片
增加编辑按钮。
技术分享图片
接下来要判断点击的是哪个单元格的按钮。iview里面的button有自带的click事件,所以这里要用on-的前缀 后面拼上click
技术分享图片
直接没有传参数的调用,记得要用大括号,括起来。
技术分享图片
技术分享图片
传参数要用.bind去执行,要在this上去执行,第一个参数是this
技术分享图片
对象结构赋值的形式去写。传入row、index、column
技术分享图片
技术分享图片
方法这里就要以同样的方式去接收
技术分享图片


技术分享图片

技术分享图片
拼接edittingId
技术分享图片
当点击的时候,要把默认的数据填进去
技术分享图片

技术分享图片

技术分享图片
加个样式
技术分享图片
技术分享图片
内容和输入框是二选一的形式
如果当前的拼接的edttingId是当前的,那么显然input标签。
技术分享图片
技术分享图片
技术分享图片
把input标签的代码移到这里
技术分享图片
点击才会显示输入框
技术分享图片
给input绑定事件。input我们平时用的时候是用v-model去绑定。v-model就相当于绑定value值同时绑定一个input事件,通过input事件修改这个value值。在这里我们要接收这个input事件
技术分享图片
定义一个全局的变量去接收它
技术分享图片
这样每次修改内容的时候,就把它绑定到到这个edttingContent变量里面。
技术分享图片
把这提取出来一个常量。
技术分享图片

技术分享图片
点击编辑后,这里编程保存。
技术分享图片
判断,当前点击是编辑状态
技术分享图片
否则就让处于编辑状态。
技术分享图片
我们要修改传入的tableData。所以这里改成用 v-model去绑定tableData
技术分享图片
那么组件内属性就要用value了。这是固定的写法
技术分享图片
这里需要把value值深拷贝一份去修改深拷贝后的数组,然后把这个数组通过emit传到父组件内。
技术分享图片

深拷贝

深拷贝我们安装一个插件 。自己安装。
技术分享图片
先引进来
技术分享图片

技术分享图片
修改后点保存,只是console输出了。
技术分享图片
修改后把this.edittingId变成一个空的字符串
技术分享图片
这样这个内容就编辑好了
技术分享图片
再添加一个事件,我们一般是需要获取你编辑的是哪一行哪一列。on-edit把编辑的信息都导出去。
技术分享图片
再增加一个NewValue告诉 父组件,更新后的值是什么
技术分享图片
保存后,把这个edittingContent也变成空
技术分享图片

父组件内接收这个事件

接收这四个值,并打印出来。
技术分享图片
编辑--保存后--
技术分享图片
编辑后的值
技术分享图片
后端如果获取了新的数据,如果表头也发生了变化。所以我们要监听columns的更新
技术分享图片
用watch监听。首先把这套逻辑提取出来封装成一个方法。
技术分享图片
监听columns,如果更新了我们再执行一下
技术分享图片
这样我们编辑单个单元格就完成了
技术分享图片
技术分享图片

封装第二个表格

可以同时编辑多个单元格
技术分享图片
引入这个组件
技术分享图片
传的数据还是这两个
技术分享图片
技术分享图片
刚才是编辑一个单元格,可以通过唯一的id去实现的。没个单元格都可以变为同时编辑的状态,所有的都显示输入框,那么就不能通过这个唯一id来实现了。所以这个时候,应该是两份数据,把传进来的表格数据copy一份,然后在这个上面,给这个数据对象做数据,每一行都来维护一个编辑状态。
比如第一行,它是一个对象,里面有三个字段。我把编程编辑状态的这一列key传进去放在一个数组里。通过判断当前的key,这一行的key在不在这个数组里 ,来判断它是不是显示状态。
技术分享图片

实际操作开始

我们还是在之类进行改造。首先还是判断这个columns,判断当前有没有可编辑的。
技术分享图片
数据字段上给他一个新的字段keyArray
技术分享图片
每一行的数据对象上添加edittingKeyArr
技术分享图片
如果行数据对象上有这个keyArr这个字段,
技术分享图片
并且当前这个column.key在这个数组里,那就说明你这一行这一列是编辑状态下,那么我们就显示这个输入框。
技术分享图片
下面同样的判断条件
技术分享图片

技术分享图片
这里先深拷贝一份
技术分享图片
我们要判断当前行数据是 有没有的, 如果有就取里面的edittingKeyArr如果没有就是空的数组[]
技术分享图片
数据变了的时候,要把value重新拷贝一下。所以监听value值的变化,值变的时候也执行下this.handleColumns()方法
技术分享图片
取当前行上的edittingKeyArra.如果有这个值说明是点击过当前行按钮的 。因为我们点一下会把这个key传进去。
技术分享图片
还是先来写没有这个edittingKeyArra的情况吧。
判断rowObj这个对象上有edittingKeyArr属性并且,edittingKeyArr.lenhth表示里面是有东西的,这里也就是length不为0的意思,
技术分享图片
那么我们就把edittingKeyArr里面拆分出来 ,通过三个点的操作符,并且把column.key当前行的key值,也放到这个数组里面。
技术分享图片
技术分享图片
没有这个字段,那么就把当前column.key添加进去。
技术分享图片

技术分享图片
这样还不够,这样修改这个数组,还不是一个深度的watch
技术分享图片
使用splice才会触发这个视图的更新。
splice会在你这个index索引的位置上,第二个参数传入要删除几个元素,第三个参数是你要添加的元素。删掉一个添加一个相当于是一个替换
技术分享图片
这里为0,先来测试下
技术分享图片
点击都可以编辑了
技术分享图片

点击保存,变成编辑状态

我们要判断当前行的key在不在数组里。在的话,说明它是编辑状态,
技术分享图片
如果有这个数组,
技术分享图片
那么就取索引号,
技术分享图片
没有这个数组,直接就-1
技术分享图片
如果大于-1 说明在这个数组里面找到了当前这个单元格的key。说明他就是编辑状态。
技术分享图片

技术分享图片
把修改后的对象替换到insideData里。用splice方法删一个,然后替换一个。
技术分享图片
通过提交一个input事件
技术分享图片
来触发父组件的v-model 来替换传进来的tableData数据。
技术分享图片
同时触发on-edit事件
技术分享图片
下面两行代码删掉。删掉后如下。
技术分享图片
测试修改后,没有替换
技术分享图片
输出值,看下实际的有没有被改变
技术分享图片
技术分享图片
值没有被改变 ,还是21
技术分享图片

是因为我们的handleInput还没有修改。文本框的值改变了要触发handleInput事件
技术分享图片
用bind来绑定,传入三个值row、index、column这三个值
技术分享图片

技术分享图片
第四个参数就是原来默认传入的值。前三个就是上面传入的值。
技术分享图片
修改后视图更新了
技术分享图片

注意事项


在封装这个组件的时候,有些人会遇到这么个问题,直接去修改这个value值。
技术分享图片
修改的时候你不是修改的insideData。而是你通过一个事件
技术分享图片
通过input事件每次修改的时候,都触发新的值,你是在handleInput里面去做input,然后去提交。然后父组件修改tableData
技术分享图片
这样就会有问题了。你每次在文本框内修改内容的时,其实都是通过input事件把修改后的东西,修改之后然后再新的表格数据那个数组,推送到父组件,父组件值改变之后,你绑定的这个tableData改变之后呢,他其实是会重新渲染这个组件,因为数据变了。视图也要变化。
技术分享图片 

那你这个时候重新渲染,输入框就被重新渲染了,你现在是编辑的状态,是获取焦点了。重新渲染的焦点就消失了。你再继续输入就没法输入了。所以你就需要输入一次,点一下文本框旁边的空白,点击获取焦点输入一下。
技术分享图片

演示这个效果

在这个地方触发input
技术分享图片
输入一下焦点就失去了,是因为这个表格组件重新渲染了。再点击文本框才能输入,但是再输入一次,又没法输入了。
技术分享图片
所以这个地方不是在这里去触发input,而是在点完保存之后,再去重新触发视图的渲染。这个时候就不会有问题了。
技术分享图片

技术分享图片
那么可以同时编辑多个单元的组件,我们就封装完成了 

注意点

就是在jsx里面没法使用v-if 等这些指令的,
技术分享图片

要通过在花括号里写原生的js逻辑
技术分享图片

绑定事件的时候呢,不需要传参数就可以直接这样
技术分享图片
如果需要传参数,就需要用bind方法,绑定到这个this上。
技术分享图片
箭头函数的方式传值
技术分享图片
 

本节代码

技术分享图片

 

结束

 

17.Vue技术栈开发实战-可编辑表格的实现

原文:https://www.cnblogs.com/wangjunwei/p/13252604.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!