Element--简单的二次封装tree组件
程序员文章站
2022-06-08 09:31:24
...
<template>
<div class="about">
<myTree :data.sync="data" :fileDrop="fileDrop" :diectoryDrop="diectoryDrop" :del="del"></myTree>
</div>
</template>
<script>
import myTree from '../components/myTree.vue'
export default {
components: {
myTree
},
data () {
return {
data: [],
fileDrop: [{ text: 'rm', value: '删除文件' }],
diectoryDrop: [
{ text: 'rn', value: '修改名字' },
{ text: 'rm', value: '删除文件夹' }
]
}
},
mounted () {
this.ff()
},
methods: {
del (id) {
// 此方法必须返回一个Promise
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 3000)
})
},
ff () {
const data = {
code: 0,
parent: [
{ name: '文件夹1', pid: 0, id: 1 },
{ name: '文件夹2', pid: 0, id: 2 },
{ name: '文件夹3', pid: 0, id: 3 },
{ name: '文件夹1-1', pid: 1, id: 4 },
{ name: '文件夹2-', pid: 2, id: 5 }
],
child: [
{ name: '文件1', pid: 1, id: 10001 },
{ name: '文件2', pid: 1, id: 10002 },
{ name: '文件2-1', pid: 2, id: 10003 },
{ name: '文件2-2', pid: 2, id: 10004 },
{ name: '文件1-1-1', pid: 4, id: 10005 },
{ name: '文件2-1-1', pid: 5, id: 10006 }
]
}
data.parent.forEach((item) => (item.type = 'parent'))
// 格式化数据 扁平的数据如何变多层数据 递归数据
const allData = [...data.parent, ...data.child]
this.data = allData
}
}
}
</script>
<template>
<el-tree :data="list" default-expand-all :expand-on-click-node="false" :render-content="render"></el-tree>
</template>
<script>
import _ from 'lodash'
export default {
name: 'tree',
props: {
data: {
type: Array,
default: () => []
},
fileDrop: {
type: Array,
default: () => []
},
diectoryDrop: {
type: Array,
default: () => []
},
del: Function
},
data () {
return {
list: [],
currentId: '', // 点击编辑的时候的id
currentContent: '' // 当前编辑的内容
}
},
beforeCreate () {
console.log('子初始化')
},
watch: {
data () {
this.transfromData()
}
},
methods: {
transfromData () {
// 对数据进行克隆
const allData = _.cloneDeep(this.data)
// 格式化数据 扁平的数据如何变多层数据 递归数据
// 映射数据 例如:{1:{name:'xxx',id:1}} id为当前id pid为父亲id
// memo:计算后的返回值 初始值为reduce函数的参数二
// current:当前函数
const treeMap = allData.reduce((memo, current) => {
current.label = current.name
memo[current.id] = current
return memo
}, {})
console.log(treeMap)
const res = allData.reduce((arr, current) => {
// 拿到当前项的父id去映射变表treeMap中找 没有找到自己就是父亲
const pid = current.pid
const parent = treeMap[pid]
if (parent) {
parent.children
? parent.children.push(current)
: (parent.children = [current])
} else if (pid === 0) {
arr.push(current)
}
return arr
}, [])
this.list = res
},
isParent (data) {
return data.type === 'parent'
},
handleRename (data) {
// 重命名
this.currentId = data.id
this.currentContent = data.name
},
remove (id) {
const list = _.cloneDeep(this.data)
console.log(id)
const arr = list.filter((item) => {
return item.id !== id
})
// .sync 用法
this.$emit('update:data', arr)
this.$message({
type: 'success',
message: '删除成功!'
})
},
handleRemove (data) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
// 判断
// 用户传递了删除方法就调用没有就直接删除
this.del
? this.del(data.id).then(() => {
this.remove(data.id)
})
: this.remove(data.id)
})
.catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
},
handleCommand (data, value) {
console.log(data, value)
if (value === 'rn') {
this.handleRename(data)
} else if (value === 'rm') {
this.handleRemove(data)
}
},
handinput (v) {
this.currentContent = v
},
render (h, { node, data, store }) {
// data:当前节点数据
const list = this.isParent(data) ? this.diectoryDrop : this.fileDrop
return (
<div>
{this.isParent(data) ? (
node.expanded ? (
<i class="el-icon-folder-opened"></i>
) : (
<i class="el-icon-folder"></i>
)
) : (
<i class="el-icon-document"></i>
)}
{data.id === this.currentId ? (
<el-input
value={this.currentContent}
on-input={this.handinput}
></el-input>
) : (
data.name
)}
{data.id !== this.currentId ? (
<el-dropdown
placement="bottom-start"
trigger="click"
on-command={this.handleCommand.bind(this, data)}
>
<span class="el-dropdown-link">
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
{list.map((item) => (
<el-dropdown-item command={item.text}>
{item.value}
</el-dropdown-item>
))}
</el-dropdown-menu>
</el-dropdown>
) : (
<span>
<button type="text" on-click={this.ok.bind(this, data)}>
确认
</button>
<button type="text" on-click={this.cannel}>
取消
</button>
</span>
)}
</div>
)
},
ok (data) {
console.log(data)
const list = _.cloneDeep(this.data)
const item = list.find((l) => {
return l.id === data.id
})
console.log(item)
item.name = this.currentContent
// .sync 用法
this.$emit('update:data', list)
this.currentId = ''
this.$message({
type: 'success',
message: '修改成功!'
})
},
cannel () {
this.currentId = ''
}
}
}
</script>
<style lang="less" scoped>
</style>
上一篇: 请问有关问题出在哪
下一篇: input 输入框的基础用法