vue-chart-tree
Version:
一个特殊布局模式结构的`vue Tree`组件
154 lines (151 loc) • 3.81 kB
HTML
<meta charset="utf-8">
<title>VueChartTree demo</title>
<script src="https://unpkg.com/vue"></script>
<script src="./vue-chart-tree.umd.js"></script>
<style>
.parent_wrapper {
padding: 16px;
overflow: hidden;
box-sizing: border-box;
border-radius: 4px;
border-left-width: 3px;
border-left-style: solid;
border-color: #F65656;
box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.05);
cursor: pointer;
background-color: #fff;
transition: all 0.15s ease;
}
.parent_wrapper:hover {
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1);
}
.parent_content {
display: flex;
align-items: flex-start;
}
.content_name {
flex: 1;
line-height: 16px;
margin: 0;
max-width: 100px;
margin-left: 10px;
overflow: hidden;
white-space: initial;
word-break: break-all;
font-size: 14px;
color: #333;
}
.name_dialog .content {
position: fixed;
top: 50%;
left: 50%;
padding: 20px 30px;
transform: translate(-50%, -50%);
background-color: #fff;
z-index: 200;
}
.name_dialog .mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.65);
z-index: 100
}
</style>
<div id="app">
<vue-chart-tree :tree-node-data="treeNodeData">
<template v-slot:default="slotProps">
<div class="parent_wrapper" @click="handlerNodeClick(slotProps.data)">
<div class="parent_content">
<p class="content_name">{{slotProps.data.treeNodeData.name}}</p>
</div>
</div>
</template>
</vue-chart-tree>
<div class="name_dialog" v-if="nameModalVisible">
<div class="mask" @click="changeNameModal"></div>
<div class="content">
<textarea rows="8" cols="60" v-model="newName"></textarea>
<button @click="updateName">确定</button>
</div>
</div>
</div>
<script>
let id = 0
// 用于生成测试数据
/**
* 用于生成测试数据
* @param maxHeight 树状图的最大深度
* @param maxChildrenHeight 节点最多拥有的直接子元素个数
* @param height 当前路径的深度
*/
function genTestData(maxHeight = 8, maxChildrenLen = 5, height = 0) {
const rootNode = {
id: id++,
name: genTestName(),
isOpen: Math.random() > 0.4
}
if (height + 1 === maxHeight) {
return rootNode
}
rootNode.children = Array(Math.round(Math.random() * maxChildrenLen)).fill(0).map(() => {
return genTestData(maxHeight, maxChildrenLen, height + 1)
})
return rootNode
}
function getCount(rootData) {
if (rootData.children) {
return rootData.children.reduce((t, c) => {
return t + getCount(c)
}, 1)
}
return 1
}
function getRootData(maxHeight = 6, maxChildrenLen = 6) {
const rootData = genTestData(maxHeight, maxChildrenLen)
console.log('节点数量: ', getCount(rootData))
return rootData
}
function genTestName() {
const nameLen = Math.random() * 10 + 10
let name = ''
while (name.length < nameLen) {
name += Math.random().toString(16).slice(2)
}
return name.slice(0, nameLen)
}
</script>
<script>
const VueChartTree = window['vue-chart-tree']
new Vue({
components: {
VueChartTree: VueChartTree.default
},
data() {
return {
treeNodeData: genTestData(),
newName: '',
activeNode: null,
nameModalVisible: false
}
},
methods: {
handlerNodeClick(activeData) {
this.activeData = activeData
this.newName = activeData.treeNodeData.name
this.changeNameModal()
},
changeNameModal() {
this.nameModalVisible = !this.nameModalVisible
},
updateName() {
this.activeData.treeNodeData.name = this.newName
// 节点高度改变,需要调用 updatePartTree 方法进行位置的重新计算
VueChartTree.updatePartTree(this.activeData.$treeNodeRefs.treeNodeRef)
this.changeNameModal()
}
}
}).$mount('#app')
</script>