zoukankan      html  css  js  c++  java
  • 19.Vue技术栈开发实战-Tree组件实现文件目录-高级实现



    首先把上节课实现的tree的逻辑进行封装,封装成一个组件,能够达到一个复用的效果。
    第二部门增加一个操作目录,每个目录,每个文件都应该可以操作,比如删除这个文件,重命名这个文件的文件名或者目录,
    3.在这个组件里面传入多个值,而且每次做更新会同时更新这多个值,如果一个值在组件内需要更新的话, 我们可以用v-model,如果多个值呢?我们来学习一下替代方案。
    最后给这个组件完善一下,增加一些钩子函数。来满足我们实际业务中的需求。

    开始

    首先我们要把这个tree封装成一个组件,创建folder-tree这个组件,

    index.js内,先导出去

    这个地方,我们只用一个tree组件。

    给这个组件一个name值

    之前的tree组件我们只传入了转换为树状数据的data数据,然后传进去了一个render函数。

    我们现就要把它作为属性传给folder-tree组件了。引入folderTree,然后注册这个组件,并使用这个组件。

    我们之前传入的数据是转换后的,整理好的树状的数据,实际我们把它封装成一个组件,那么我应该在用的时候,尽量的减少我们自己的再做的操作,要不然这些东西都在这里做的话,就没有必要在封装了。封装的目的就是为了在复用的时候减少我们的工作,

    所以我们直接传入folderList文件夹的列表数据和文件的列表数据,在组件内不让它去做转换。



    转换的数据就是我们传递进来的属性。

    内部定义 folderTree

    res[0]是文件夹数组,res[1]是文件数组。

    把之前的render函数赋值到组件内部

    复制到了组件的内部



    样式剪切到组件的内部

    剪切到了组件的内部

    声明周期mouted钩子函数内,先调用一次,如果这个时候传进来有数据,在这里就会做这个工作。

    如果一开始没有,是异步的传进来的数据呢?所以我们要监听folderList和fileList变化的时候,都要做处理。


    和之前的效果一样

    操作目录

    接下来,来看操作目录这块。
    我们要在render的这个地方,给每个元素都加一个下拉菜单。

    下拉菜单用Dropdown这个组件。里面第一个元素是用来,显示下拉列表的元素。在jsx里面,view的组件必须用带前缀i-的方式

    在官方组件库内 搜索iocn的图标 more类型的

    复制过来是大写的Icon。

    我们要改成小写的方式

    给它设置一个size,我们的size是一个数值类型,不是字符串的类型,所以这里我们要用花括号括起来


    每一条都这么宽,想让button始终显示在最右侧

    要不然文件名,不一样长就对不齐了。给它加一个class属性



    没有效果,因为它外层裹了一个ivu-dropdown

    tree-item里面直接子元素的 .ivu-dropdown


    定义里面的列表

    用dropdownMenu让它作为一个插槽。

    移出来,和i-button是同级别的。

    鼠标放上拉颜色怪怪的,背景是灰色,并且宽度没有100%的背景色。可能是被我们tree里面的一些样式给覆盖了。

    样式被覆盖,需要我们自己写一下样式。设置了 下面的css ,没有效果

    应该还是一些样式的权重不够。看到这个ul的padding-left还是有的

    勾选去掉就可以了

    我们给这个ul加类名ivu-dropdown-menu

    item同理也加上类名为ivu-dropdown-item,这样样式就正常了。

    定义两个属性,一个是文件夹操作列表,一个是文件操作列表。这里没有设置默认值,如果是空数组的话,说明它不需要下拉菜单,所以之类我们没有设置默认值,直接让它是一个aarray类型,到时候直接是否为空就直接判断这个数组是否是undefined,如果是undefined说明它没有传入值。

    没有传dolerDrop没有传就直接不显示这个dropdown按钮了。

    调用组件的时候,传入这两个属性


    渲染传进来的菜单。对dropList做一个映射。return里面写我们jsx的内容。

    绑定一个name属性,方便我们后面知道点击了是哪一个



    为了区分开,把菜单的名称改一下





    dropdown设置右边顶部对齐。

    页面宽度比较窄的时候会显示在左侧,

    根据屏幕的边缘智能判断,显示在那一边

    dropdown添加事件

    dropdown有个on-click事件

    在jsx里面我要用on-前缀来标识,这是一个绑定的事件,事件名写在后面







    点击删除文件夹

    点击重命名,显示输入框,输入新的名字

    重命名

    首先要有一个全局的标识。

    方法需要绑定参数,用bind在this上面去绑定

    click事件原生返回的name值,它会拼在我们自定义的参数 后面

    所以这里我们第一个参数是data,第二个参数是name



    直接还可以再简写一下。如有这个data.type字段的话就用folder。,没有的话就用file

    有个这个标识之后,我们就可以判断了。如果当前编辑的id等于拼接的id那么,

    那么就显示i-input,同时给i-input绑定上input事件,

    定义方法,它的参数就是当前修改后的内容

    定义变量currentRenamingContent

    点击重命名

    文本框后面,还需要两个按钮,这里因为jsx里面要求只有一个根节点,所以用一个span标签包裹起来。

    加上两个按钮,然后输入框 让他短一点,加上一个class类名

    这里还是用计算的属性,100%减去80px

    按钮设置为small 并且类型是texxt

    点击重命名

    把状态抽到上面

    如果正在重名,那么dropDown也不显示


    保存修改事件

    点击对号以后,要替换原来的内容

    还是需要把data参数传进来

    接下里要在里面遍历一下,如果你当前修改的是文件夹目录中的一个目录的名字的话,你是要遍历文件夹列表。

    定义i为-1, 如果type类型是folder的话,也就是文件夹

    获取文件list的长度,然后循环,如果当前的item的id等于修改的id,那么就把item的name替换为修改的内容。并且用splice方法把文件夹list的item元素移除,再替换修改后的进来。

    如果是文件列表的话。下面就是循环fileList

    把这部分抽离出来封装成一个公共的方法,下面调用的时候 直接传参数list进去就可以了。

    让文本框消失



    事件绑定错了值了,绑定到了差号上了。移动到对号上





    缺点,我们直接在这个组件内修改filstList和folderList肯定是不行的

    修改父组件内的值

    引入深拷贝





    修改没有效果

    先把修改后的值return 出来先

    通过事件抛到父组件内去修改。在父组件内,我们绑定了两个值,一个folder-list一个是file-list .如果只绑定一个值的话 ,我们可以用v-model来做,但是我们这里绑定了两个值。

    这里我们用之前讲过的.sync修饰符。父组件间内,这里都加上sync修饰符。

    子组件内怎么更新呢?update冒号 这是固定的。

    然后要更新哪个值,folderList是父组件传过来的值。




    修改文件同理

    这里是拿到了name赋值给title,所以我们修改了name的值 也是可以的。

    同时这里监听了两个list的变化,一但有变化就重新触发 转换的方法,上面把name赋值给title,所以我们修改的时候修改的name值也是对的。

    删除操作

    删除要提醒用户,是否要删除

    封装一个方法,判断是删除文件夹还是文件。

    然后下面判断是文件夹还是文件。




    确定要删除执行的方法

    判断是否是文件夹,如果是文件夹,那么更新的就是folderList,如果是文件更新的就是fileList了。

    判断要删除的是哪个对象, 就深拷贝哪个对象

    删除操作可以使用filter过滤操作,return的就是不需要过滤掉的,就是你要的
    返回的是id不等于当前要删除的id的。那就是删了以后剩下的元素。

    emit事件









    删除后,文件夹就合住了 需要重新打开。这样体验就很不好。

    删除后,文件夹保持展开的状态

    tree组件要给当前的这个item一个属性,设置一个值,是否展开子节点,如果设置为true就会展开这一节

    需要一个方法,传入一个id。你要展开哪一个目录,就把文件夹id传进去。
    在util里封装一个方法。用map方法做一个映射。

    如果是文件夹,并且找到了这个id。那么就展开这个节点



    如果item.children里面有一个children的expand为true的话 那么就返回。



    所以这里的判断就是判断这个点的子节点有一个是展开的。那么就展开当前这个节点。

    否则就不展开。

    最后返回当前的item

    最后把返回的新数组 return出去


    在组件内使用一下

    调用展开的方法



    没起作用

    放在this.$nextTick里面执行试一下




    有效果了


    刚才没起作用的原因:可能是删除之后,视图还没有更新完 我们就去展开这节点,所以有问题 。

    钩子函数

    前端删除了,但是后端的服务删除报错了。那么这样前后端的数据就不一致。
    所以点击删除 ,应该先去调用接口去做删除操作。删除成功了再往下继续。
    这里就引入钩子函数。

    返回一个Promise。这里我们写的是promise,实际的开发过程中,应该调用的是一个接口。这里我们暂时用Promise来代替。

    模拟一个数据的延迟2秒后 成功返回。

    组件内接收,方法

    默认可以不设置。不设置的话,就是你比较有信心,不需要这样的一个钩子。

    如果有这个函数。那么后面的操作都放在这个函数的then里面。

    报错了就提示一下

    把展开操作移到上面去

    folderId也移到上面去。

    我们现在错误设置的为null。那就是没有错误


    2秒后成功删除


    这里改成错误的





     

    本节代码


     

    结束

  • 相关阅读:
    tcl基本语法
    linux hostid与lmhostid
    linux下uptime命令
    介绍一下 WebApplicationContext?
    Spring 由哪些模块组成?
    怎样开启注解装配?
    解释不同方式的自动装配 ?
    @Qualifier 注解有什么用?
    解释 Spring 框架中 bean 的生命周期?
    如何在 spring 中启动注解装配?
  • 原文地址:https://www.cnblogs.com/wangjunwei/p/13270121.html
Copyright © 2011-2022 走看看