Tree组件实现文件目录-基础实现

  1. 封装文件目录组件

src\views\folder-tree\folder-tree.vue

<template>
<div class="folder-wrapper">
<folder-tree :folder-list="folderList" :file-list="fileList"/>
</div>
</template>
<script>
import { getFolderList, getFileList } from '@/api/data';
import FolderTree from '_c/folder-tree';
export default {
components: {
FolderTree
},
data () {
return {
folderList: [],
fileList: []
}
},
mounted () {
Promise.all([getFolderList(), getFileList()]).then(res => {
this.folderList = res[0]
this.fileList = res[1]
})
}
}
</script>
<style lang="less">
.folder-wrapper {
width: 300px;
}
</style>

src\components\folder-tree\folder-tree.vue

<template>
<div class="folder-wrapper">
<Tree :folder-list="folderList" :file-list="fileList" :data="folderTree" :render="renderFunc"></Tree>
</div>
</template>
<script>
import { putFileInFolder, transferFolderToTree } from '@/lib/util'
export default {
name: 'FolderTree',
data () {
return {
folderTree: [],
renderFunc: (h, { root, node, data }) => {
return (
<div class="tree-item">
{data.type === 'folder' ? (
<icon
type="ios-folder"
color="#2d8cf0"
style="margin-right: 5px;"
/>
) : (
''
)}
{data.title}
</div>
)
}
}
},
props: {
folderList: {
type: Array,
default: () => []
},
fileList: {
type: Array,
default: () => []
}
},
methods: {
transData () {
this.folderTree = transferFolderToTree(
putFileInFolder(this.folderList, this.fileList)
)
}
},
watch: {
folderList () {
this.transData()
},
fileList () {
this.transData()
}
},
mounted () {
this.transData()
}
}
</script>
<style lang="less">
.tree-item {
display: inline-block;
width: ~"calc(100% - 50px)";
height: 30px;
line-height: 30px;
}
</style>
  1. 操作目录

  2. 多个属性v-model替代方案

  3. 增加钩子函数

src\views\folder-tree\folder-tree.vue

<template>
<div class="folder-wrapper">
<!-- <Tree :data="folderTree" :render="renderFunc"></Tree> -->
<folder-tree
:folder-list.sync="folderList"
:file-list.sync="fileList"
:folder-drop="folderDrop"
:file-drop="fileDrop"
:beforeDelete="beforeDelete"
/>
</div>
</template> <script>
import { getFolderList, getFileList } from '@/api/data'
import FolderTree from '_c/folder-tree'
export default {
components: {
FolderTree
},
data () {
return {
folderList: [],
fileList: [],
folderDrop: [
{
name: 'rename',
title: '重命名'
},
{
name: 'delete',
title: '删除文件夹'
}
],
fileDrop: [
{
name: 'rename',
title: '重命名'
},
{
name: 'delete',
title: '删除文件'
}
]
}
},
methods: {
beforeDelete () {
return new Promise((resolve, reject) => {
setTimeout(() => {
let error = new Error('error')
if (!error) {
resolve()
} else reject(error)
}, 2000)
})
}
},
mounted () {
Promise.all([getFolderList(), getFileList()]).then(res => {
this.folderList = res[0]
this.fileList = res[1]
})
}
}
</script> <style lang="less">
.folder-wrapper {
width: 300px;
}
</style>

src\components\folder-tree\folder-tree.vue

<template>
<Tree :data="folderTree" :render="renderFunc"></Tree>
</template> <script>
import {
putFileInFolder,
transferFolderToTree,
expandSpecifiedFolder
} from '@/lib/util'
import clonedeep from 'clonedeep'
export default {
name: 'FolderTree',
data () {
return {
folderTree: [],
currentRenamingId: '',
currentRenamingContent: '',
renderFunc: (h, { root, node, data }) => {
const dropList =
data.type === 'folder' ? this.folderDrop : this.fileDrop
const dropdownRender = dropList.map(item => {
return <dropdownItem name={item.name}>{item.title}</dropdownItem>
})
const isRenaming =
this.currentRenamingId === `${data.type || 'file'}_${data.id}`
return (
<div class="tree-item">
{data.type === 'folder' ? (
<icon
type="ios-folder"
color="#2d8cf0"
style="margin-right: 10px;"
/>
) : (
''
)}
{isRenaming ? (
<span>
<i-input
value={data.title}
on-input={this.handleInput}
class="tree-rename-input"
/>
<i-button
size="small"
type="text"
on-click={this.saveRename.bind(this, data)}
>
<icon type="md-checkmark" />
</i-button>
<i-button size="small" type="text">
<icon type="md-close" />
</i-button>
</span>
) : (
<span>{data.title}</span>
)}
{dropList && !isRenaming ? (
<dropdown
placement="right-start"
on-on-click={this.handleDropdownClick.bind(this, data)}
>
<i-button size="small" type="text" class="tree-item-button">
<icon type="md-more" size={12} />
</i-button>
<dropdownMenu slot="list">{dropdownRender}</dropdownMenu>
</dropdown>
) : (
''
)}
</div>
)
}
}
},
props: {
folderList: {
type: Array,
default: () => []
},
fileList: {
type: Array,
default: () => []
},
folderDrop: Array,
fileDrop: Array,
beforeDelete: Function
},
watch: {
folderList () {
this.transData()
},
fileList () {
this.transData()
}
},
methods: {
transData () {
this.folderTree = transferFolderToTree(
putFileInFolder(this.folderList, this.fileList)
)
},
isFolder (type) {
return type === 'folder'
},
handleDelete (data) {
const folderId = data.folder_id
const isFolder = this.isFolder(data.type)
let updateListName = isFolder ? 'folderList' : 'fileList'
let list = isFolder
? clonedeep(this.folderList)
: clonedeep(this.fileList)
list = list.filter(item => item.id !== data.id)
this.$emit(`update:${updateListName}`, list)
this.$nextTick(() => {
expandSpecifiedFolder(this, this.folderTree, folderId)
})
},
handleDropdownClick (data, name) {
if (name === 'rename') {
this.currentRenamingId = `${data.type || 'file'}_${data.id}`
} else if (name === 'delete') {
this.$Modal.confirm({
title: '提示',
content: `您确定要删除${
this.isFolder(data.type) ? '文件夹' : '文件'
}《${data.title}》吗?`,
onOk: () => {
this.beforeDelete
? this.beforeDelete()
.then(() => {
this.handleDelete(data)
})
.catch(() => {
this.$Message.error('删除失败')
})
: this.handleDelete(data)
}
})
}
},
handleInput (value) {
this.currentRenamingContent = value
},
updateList (list, id) {
let i = -1
let len = list.length
while (++i < len) {
let folderItem = list[i]
if (folderItem.id === id) {
folderItem.name = this.currentRenamingContent
list.splice(i, 1, folderItem)
break
}
}
return list
},
saveRename (data) {
const id = data.id
const type = data.type
if (type === 'folder') {
const list = this.updateList(clonedeep(this.folderList), id)
this.$emit('update:folderList', list)
} else {
const list = this.updateList(this.fileList, id)
this.$emit('update:fileList', list)
}
this.currentRenamingId = ''
}
},
mounted () {
this.transData()
}
}
</script> <style lang="less">
.tree-item {
display: inline-block;
width: ~"calc(100% - 50px)";
height: 30px;
line-height: 30px;
& > .ivu-dropdown {
float: right;
}
ul.ivu-dropdown-menu {
padding-left: 0;
}
li.ivu-dropdown-item {
margin: 0;
padding: 7px 16px;
}
.tree-rename-input {
width: ~"calc(100% - 80px)";
}
}
</style>

Vue iview Tree组件实现文件目录-高级实现的更多相关文章

  1. Vue iview Tree组件实现文件目录-基础实现

    注册页面路由 router/router.js { path: 'folder_tree', name: 'folderTree', component: () => import('@/vie ...

  2. VUE -- iview table 组件 中使用 upload组件 上传组件 on render 事件不会触发问题

    碰到的问题是: upload 组件在 on中写的监听事件不会被触发 在 props 中来监听:==>

  3. vue iview tree checked改变 不渲染的问题

    子级的状态 改为checked=false  需要把父的状态改为 false

  4. vue - iview UI组件的col标签报错 x-invalid-end-tag

    https://blog.csdn.net/xiao199306/article/details/80430087

  5. Vue ElementUI Tree组件 回显问题(设置选择父级时会全选所有的子级,有此业务场景是不适合的)

    业务场景下有这样的问题 业务需求需要保存前端 半选节点 解决方案 let checked = this.$refs.menuTree.getCheckedKeys(); //此方法获取半选节点 let ...

  6. 【技术博客】使用iview的Tree组件写一棵文件树

    本次项目的前端部分使用vue框架+iview组件构建,其中IDE的文件树部分使用了iview的Tree组件,但是Tree组件本身的接口功能极其有限,网上的相关资料也不多,在使用时费了一番功夫才摸索清楚 ...

  7. 基于iview 封装一个vue 表格分页组件

    iview 是一个支持中大型项目的后台管理系统ui组件库,相对于一个后台管理系统的表格来说分页十分常见的 iview是一个基于vue的ui组件库,其中的iview-admin是一个已经为我们搭好的后天 ...

  8. iView中Tree组件children中动态checked选中后取消勾选再选中无效问题

    如题,我有一个Tree组件,动态更新check选中子级列表的时候,取消勾选了再点击选中时复选框样式不是勾选状态,但是数据已经有了. 对此解决方案是:将初始化时Tree组件data数据深拷贝一遍再去判断 ...

  9. Vue 2.0 组件库总结

    UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...

随机推荐

  1. 为什么?为什么?Java处理排序后的数组比没有排序的快?想过没有?

    先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题 ...

  2. WIN10家庭版安装ORACLE的问题

    第一次安装成功后可启动ORACLE服务,重启计算机后服务监听无法启动,建议替换系统

  3. Docker 的前世今生

    虚拟化 「要解释清楚 Docker,首先要解释清楚容器(Container)的概念」.要解释容器的话,就需要从操作系统说起.操作系统太底层,细说的话一两本书都说不清楚.这里就一句话来总结一下:操作系统 ...

  4. 使用hexo+github搭建博客

    https://blog.csdn.net/qq_36667170/article/details/105789610这一篇已经写得很详细了,下面的内容是我操作的时候遇到的问题及解决方法. 1.下载N ...

  5. java基础-03:注释

    1.注释的意义: (1) 为了更好的阅读自己编写的代码,方便日后代码维护,建议添加注释. (2) 有利于团队协作. (3) 代码即文档.程序源代码是程序文档的重要组成部分. 2.注释分类 (1) 单行 ...

  6. Jmeter 常用函数(30)- 详解 __if

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 判断给定条件是否成立 语法格式 ${_ ...

  7. 为什么 max() 应该写成 b < a ? a : b 呢?

    在 < C++ Templates 2nd Edition >Chapter 1 中,作者将 max() 模板定义如下: template <typename T> T max ...

  8. RabbitMQ set password

    问题: -- ::09.387 ERROR oslo.messaging._drivers.impl_rabbit [req-51faf017-4f1f-4a24-ab79-624b302b839b ...

  9. openstack nova 虚机镜像后端提取

    参考链接:https://www.cnblogs.com/storymedia/p/4500186.html 1.nova 创建的虚机后端目录 其中的base是虚机基础镜像,创建虚机会根据这个基础镜像 ...

  10. windows下cmd命令行计算文件hash值

    命令:certutil -hashfile certutil -hashfile D:\.exe MD5 certutil -hashfile D:\.exe SHA1 certutil -hashf ...