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秒后成功删除


这里改成错误的





 

本节代码


 

结束

 

posted @ 2020-07-09 00:07  高山-景行  阅读(1212)  评论(2编辑  收藏  举报