Vue iview Tree组件实现文件目录-高级实现
封装文件目录组件
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>
操作目录
多个属性v-model替代方案
增加钩子函数
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组件实现文件目录-高级实现的更多相关文章
- Vue iview Tree组件实现文件目录-基础实现
注册页面路由 router/router.js { path: 'folder_tree', name: 'folderTree', component: () => import('@/vie ...
- VUE -- iview table 组件 中使用 upload组件 上传组件 on render 事件不会触发问题
碰到的问题是: upload 组件在 on中写的监听事件不会被触发 在 props 中来监听:==>
- vue iview tree checked改变 不渲染的问题
子级的状态 改为checked=false 需要把父的状态改为 false
- vue - iview UI组件的col标签报错 x-invalid-end-tag
https://blog.csdn.net/xiao199306/article/details/80430087
- Vue ElementUI Tree组件 回显问题(设置选择父级时会全选所有的子级,有此业务场景是不适合的)
业务场景下有这样的问题 业务需求需要保存前端 半选节点 解决方案 let checked = this.$refs.menuTree.getCheckedKeys(); //此方法获取半选节点 let ...
- 【技术博客】使用iview的Tree组件写一棵文件树
本次项目的前端部分使用vue框架+iview组件构建,其中IDE的文件树部分使用了iview的Tree组件,但是Tree组件本身的接口功能极其有限,网上的相关资料也不多,在使用时费了一番功夫才摸索清楚 ...
- 基于iview 封装一个vue 表格分页组件
iview 是一个支持中大型项目的后台管理系统ui组件库,相对于一个后台管理系统的表格来说分页十分常见的 iview是一个基于vue的ui组件库,其中的iview-admin是一个已经为我们搭好的后天 ...
- iView中Tree组件children中动态checked选中后取消勾选再选中无效问题
如题,我有一个Tree组件,动态更新check选中子级列表的时候,取消勾选了再点击选中时复选框样式不是勾选状态,但是数据已经有了. 对此解决方案是:将初始化时Tree组件data数据深拷贝一遍再去判断 ...
- Vue 2.0 组件库总结
UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...
随机推荐
- SpringBoot --- 自定义 Starter
SpringBoot --- 自定义 Starter 创建 1.需要创建一个新的空工程 2.新的工程需要引入两个模块 一个Maven 模块 作为启动器 一个SpringBoot 模块 作为自动配置模块 ...
- (转)mybatis一级缓存二级缓存
一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...
- vue+leaflet
1.index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- Jmeter 常用函数(23)- 详解 __longSum
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.htm 作用 计算两个或多个长值的和 注意 当值不在 ...
- Netbox 开源 IPAM 管理工具搭建详细流程
原文链接:Netbox 开源 IPAM 管理工具搭建详细流程 参考资料:https://netbox.readthedocs.io/en/stable/ PostgreSQL数据库安装 1.yum 下 ...
- Python1--简介及基础语法
0. 简介 Python易于学习的编程语言,有很多现成的第三方库可以调用,不用重复造轮子,老话说:"人生苦短,我用 Python" 1. 安装Python Mac:brew ins ...
- 你竟然不知道Java中可以用 :: 吗?
简介 Java8中方法引用分为三种,方法引用通过一对双冒号:: 来表示,方法引用是一种函数式接口的另一种书写方式 静态方法引用,通过类名::静态方法名, 如 Integer::parseInt 实例方 ...
- 数据中台实战(一):以B2B电商亿订为例,谈谈产品经理视角下的数据埋点
本文以B2B电商产品“亿订”为实例,与大家一同谈谈数据中台的数据埋点. 笔者所在公司为富力环球商品贸易港,是富力集团旗下汇聚原创设计师品牌及时尚买手/采购商两大社群,通过亿订B2B电商.RFSHOWR ...
- Java8中的Stream API
本篇文章继续介绍Java 8的另一个新特性——Stream API.新增的Stream API与InputStream和OutputStream是完全不同的概念,Stream API是对Java中集合 ...
- 前端框架之vue初步学习
Vue.js介绍: Vue.js是一个构建数据驱动的web界面的渐进式框架.Vue.js的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件.它不仅易于上手,还便于与第三方库或既有项目整合 ...