zoukankan      html  css  js  c++  java
  • 17.Vue技术栈开发实战-可编辑表格的实现

    通过对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上。

    箭头函数的方式传值

     

    本节代码



     

    结束

  • 相关阅读:
    没有找到MSVCR100.dll解决方法
    Python用subprocess的Popen来调用系统命令
    我是怎样成长为系统架构师的
    【java读书笔记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
    SQLite的SQL语法
    MVC中使用AuthorizeAttribute做身份验证操作
    windows知识点
    java实现第五届蓝桥杯斐波那契
    java实现第五届蓝桥杯绳圈
    java实现第五届蓝桥杯绳圈
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/13252604.html
Copyright © 2011-2022 走看看