实现功能
- Tree 组件使用
- 扁平数据树状化
- 自定义组件结构
实现效果
![](https://img.haomeiwen.com/i3944205/08a69a1a2597aa06.png)
实现过程
拼装数据
title下包含children
![](https://img.haomeiwen.com/i3944205/ba5ee1d78f06f27b.png)
数据封装工具类 lib/util.js
// 添加文件进文件夹
export const putFileInFolder = (folderList, fileList) => {
const folderListCloned = clonedeep(folderList);
const fileListCloned = clonedeep(fileList);
return folderListCloned.map(folderItem => {
const folderId = folderItem.id;
let index = fileListCloned.length;
while (--index >= 0) {
const fileItem = fileListCloned[index];
if (fileItem.folder_id === folderId ) {
const file = fileListCloned.splice(index,1)[0];
file.title = file.name;
if (folderItem.children) folderItem.children.push(file);
else folderItem.children = [file];
}
};
folderItem.type = 'folder';
return folderItem;
});
};
// 扁平文件夹组装为树状
export const transformFolderToTree = folderList => {
if (!folderList.length) return [];
const folderListCloned = clonedeep(folderList);
const handle = id => {
let arr = [];
folderListCloned.forEach(folder => {
if (folder.folder_id === id) {
const children = handle(folder.id);
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
<template>
<div class="folder-wrapper">
<Tree :data="folderTree" :render="renderFunc"></Tree>
</div>
</template>
<script>
import { getFolderList, getFileList } from "@/api/data";
import { putFileInFolder, transformFolderToTree } from "@/lib/util";
export default {
data () {
return {
folderList: [],
fileList: [],
folderTree: [],
renderFunc: (h, { root, node, data }) => {
return (
<div class="tree-item">
{ 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 = transformFolderToTree(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>
Mock 模拟数据
// api/data.js 定义接口
export const getFolderList = () => {
return axios.request({
url: '/getFolderList',
method: 'get'
})
}
export const getFileList = () => {
return axios.request({
url: '/getFileList',
method: 'get'
})
}
//mock 提供数据
import { doCustomTimes } from '@/lib/tools'
import Mock from 'mockjs'
export const getFileList = () => {
const template = {
'name|5': '@cword',
'create_time': '@datetime',
'folder_id|1-5': 0,
'id|+1': 1000
};
let arr = [];
doCustomTimes(10, () => {
arr.push(Mock.mock(template));
});
return arr;
};
export const getFolderList = () => {
const template1 = {
'name|1': '@word',
'create_time': '@datetime',
'folder_id': 0,
'id|+1': 1
};
const template2 = {
'name|1': '@word',
'create_time': '@datetime',
'folder_id|+1': 1,
'id|+1': 4
};
let arr = [];
doCustomTimes(3, () => {
arr.push(Mock.mock(template1));
});
doCustomTimes(2, () => {
arr.push(Mock.mock(template2));
});
return arr;
};
// lib/tool.js 定义doCustomTimes
export const doCustomTimes = (times, callback) => {
let i = -1
while (++i < times) {
callback()
}
}
// Mock/index.js 调用
import Mock from 'mockjs'
import { getFolderList, getFileList } from './response/data'
Mock.mock('/getFolderList',getFolderList)
Mock.mock('/getFileList',getFileList)
网友评论