乐趣区

第十八课时: Tree组件实现文件目录-基础实现

Tree 组件使用
iview 树形控件要求的数据格式
data1: [
{
title: ‘parent 1’,
expand: true,
children: [
{
title: ‘parent 1-1’,
expand: true,
children: [
{
title: ‘leaf 1-1-1’
},
{
title: ‘leaf 1-1-2’
}
]
},
{
title: ‘parent 1-2’,
expand: true,
children: [
{
title: ‘leaf 1-2-1’
},
{
title: ‘leaf 1-2-1’
}
]
}
]
}
]
扁平数据树树状化
扁平数据树: 通过接口请求到文件夹的数组 folderList 和文件的数组 fileList
folderList:[{name: “smifqwe”, creat_time: “1973-07-26 06:27:55”, folder_id: 0, id: 1},{name: “gkcn”, creat_time: “2001-03-27 00:42:02”, folder_id: 0, id: 2},{name: “iod”, creat_time: “1971-05-15 05:10:04”, folder_id: 0, id: 3},{name: “rldt”, creat_time: “1979-06-29 02:43:24”, folder_id: 1, id: 4},{name: “kuqiuwqp”, creat_time: “2009-06-25 06:53:42”, folder_id: 2, id: 5}]
(folder_id 为此文件夹应该放的 id 位置,0 代表应该放在根目录,1 代表应该放在 id 为 1 的文件夹下)
fileList:[{name: “ 商定么体平 ”, creat_time: “1981-01-30 19:28:51”, folder_id: 4, id: 10000},{name: “ 分命收效集 ”, creat_time: “2005-04-30 09:08:24”, folder_id: 3, id: 10001},{name: “ 立多满步始 ”, creat_time: “2012-04-08 22:18:17”, folder_id: 4, id: 10002},{name: “ 越但却求市 ”, creat_time: “1997-10-10 16:50:51”, folder_id: 3, id: 10003},{name: “ 比事期新段 ”, creat_time: “2012-12-24 12:18:55”, folder_id: 3, id: 10004},{name: “ 飞情信头南 ”, creat_time: “2010-04-05 17:53:08”, folder_id: 3, id: 10005},{name: “ 织海工志什 ”, creat_time: “1977-12-01 04:52:05”, folder_id: 1, id: 10006},{name: “ 向国求响者 ”, creat_time: “2000-06-17 01:16:57”, folder_id: 5, id: 10007},{name: “ 九起海员两 ”, creat_time: “2003-12-23 14:31:44”, folder_id: 3, id: 10008},{name: “ 适影儿公上 ”, creat_time: “2009-02-24 13:31:48″, folder_id: 3, id: 10009}]
(folder_id 为此文件应该放在对应文件夹 id 下)
需要把扁平数据树的数据转化成 iview 组件可以渲染的数据
Promise.all([getFolderList(), getFileList()]).then(res => {
// getFolderList()、getFileList() 分别得到文件夹和文件的数据,folderTree 为 iview 需要的数据
this.folderTree = transferFolderToTree(putFileInFolder(res[0], res[1]))
})

export const putFileInFolder = (folderList, fileList) => {
const folderListCloned = clonedeep(folderList)
const fileListCloned = clonedeep(fileList)
// 循环文件夹数组
return folderListCloned.map(folderItem => {
// 文件夹的 id
const folderId = folderItem.id
// 文件数组的长度
let index = fileListCloned.length
// 循环文件数组
while (–index >= 0) {
const fileItem = fileListCloned[index]
// 当文件的 folder_id 等于 文件夹的 id 的时候
if (fileItem.folder_id === folderId) {
// 获取满足条件的文件
const file = fileListCloned.splice(index, 1)[0]
// 需要文件的 title 属性
file.title = file.name
// 文件夹的 children 里面是文件的数组
if (folderItem.children) folderItem.children.push(file)
else folderItem.children = [file]
}
}
// 给这个文件夹加上 type 属性,用来区别文件
folderItem.type = ‘folder’
return folderItem
})
}

export const transferFolderToTree = folderList => {
if (!folderList.length) return []
// 深赋值带文件的文件夹数组
const folderListCloned = clonedeep(folderList)
// handle 函数, 传入 id, 第一次传入 0, 是根目录
const handle = id => {
let arr = []
folderListCloned.forEach(folder => {
// 当文件夹的 folder_id 等于 传来的 id 时
if (folder.folder_id === id) {
// 调用 handle 函数,传入文件夹的 id
const children = handle(folder.id)
// 把满足情况的 folder 放入新的数组中返回回去
if (folder.children) folder.children = [].concat(folder.children, children)
else folder.children = children
folder.title = folder.name
arr.push(folder)
}
})
return arr
}
return handle(0)
}

自定义组件结构
folder-tree.vue 文件夹组件: 通过 render 函数来渲染出想要的样式, 如图:
<template>
<div class=”folder-wrapper”>
<Tree :data=”folderTree” :render=”renderFunc”></Tree>
</div>
</template>

<script>
import {getFolderList, getFileList} from ‘@/api/data’
import {putFileInFolder, transferFolderToTree} from ‘@/lib/util’
export default {
data () {
return {
folderList: [],
fileList: [],
folderTree: [],
renderFunc: (h, { root, node, data}) => {
return (
<div class=”tree-item”>
/* 如果 type 等于 folder 的时候,加一个文件夹的 icon */
{data.type === ‘folder’ ? <icon type=”ios-folder” color=”#2d8cf0″ style=”margin-right: 10px;”/> : ”}
{data.title}
</div>
)
}
}
},
mounted () {
Promise.all([getFolderList(), getFileList()]).then(res => {
this.folderTree = transferFolderToTree(putFileInFolder(res[0], res[1]))
})
}
}
</script>

<style lang=”less”>
.folder-wrapper{
width: 300px;
.tree-item{
display: inline-block;
width: ~”calc(100% – 50px)”;
height: 30px;
line-height: 30px;
}
}
</style>

退出移动版