vue 实现文件目录
Vue 实现文件目录的方法
使用递归组件实现树形结构
递归组件是处理文件目录这类嵌套数据的理想方式。通过组件调用自身实现无限层级渲染。
<template>
<div>
<ul>
<tree-item
v-for="item in treeData"
:key="item.name"
:item="item"
/>
</ul>
</div>
</template>
<script>
export default {
components: {
TreeItem: {
name: 'TreeItem',
props: ['item'],
template: `
<li>
{{ item.name }}
<ul v-if="item.children && item.children.length">
<tree-item
v-for="child in item.children"
:key="child.name"
:item="child"
/>
</ul>
</li>
`
}
},
data() {
return {
treeData: [
{
name: '文件夹1',
children: [
{ name: '文件1.txt' },
{ name: '文件2.txt' }
]
},
{
name: '文件夹2',
children: [
{
name: '子文件夹',
children: [
{ name: '文件3.txt' }
]
}
]
}
]
}
}
}
</script>
使用第三方库 vue-tree-list
对于更复杂的需求,可以使用专门处理树形结构的第三方库。
安装依赖:

npm install vue-tree-list --save
基本使用示例:
<template>
<vue-tree-list
:model="treeData"
@click="onClick"
/>
</template>
<script>
import { VueTreeList } from 'vue-tree-list'
export default {
components: {
VueTreeList
},
data() {
return {
treeData: {
name: '根目录',
children: [
{
name: '文档',
isLeaf: false,
children: [
{ name: 'readme.md', isLeaf: true }
]
}
]
}
}
},
methods: {
onClick(node) {
console.log(node)
}
}
}
</script>
动态加载目录数据
对于大型文件系统,建议实现懒加载功能,只在展开时加载子目录。

<template>
<ul>
<li
v-for="item in items"
:key="item.path"
@click="loadChildren(item)"
>
{{ item.name }}
<ul v-if="item.children && item.children.length">
<tree-item :items="item.children"/>
</ul>
<span v-if="item.loading">加载中...</span>
</li>
</ul>
</template>
<script>
export default {
name: 'TreeItem',
props: ['items'],
methods: {
async loadChildren(item) {
if (item.children || item.loading) return
item.loading = true
try {
const res = await fetch(`/api/directory?path=${item.path}`)
item.children = await res.json()
} finally {
item.loading = false
}
}
}
}
</script>
添加交互功能
增强用户体验可以添加展开/折叠、右键菜单等功能。
<template>
<li>
<div @click="toggle">
<span v-if="hasChildren">[{{ isOpen ? '-' : '+' }}]</span>
{{ item.name }}
</div>
<ul v-show="isOpen" v-if="hasChildren">
<tree-item
v-for="child in item.children"
:key="child.name"
:item="child"
/>
</ul>
</li>
</template>
<script>
export default {
name: 'TreeItem',
props: ['item'],
data() {
return {
isOpen: false
}
},
computed: {
hasChildren() {
return this.item.children && this.item.children.length
}
},
methods: {
toggle() {
if (this.hasChildren) {
this.isOpen = !this.isOpen
}
}
}
}
</script>
样式优化
添加CSS美化目录结构的外观。
ul {
list-style-type: none;
padding-left: 20px;
}
li {
margin: 5px 0;
cursor: pointer;
}
li > div:hover {
background-color: #f5f5f5;
}
.folder-icon:before {
content: '📁';
margin-right: 5px;
}
.file-icon:before {
content: '📄';
margin-right: 5px;
}
以上方法可以根据实际需求组合使用,构建功能完善的文件目录组件。






