这篇文章主要为大家详细介绍了Vue 实现树形视图数据功能,具有一定的参考价值,可以用来参考一下。
感兴趣的小伙伴,下面一起跟随四海网的小编两巴掌来看看吧!
利用简单的树形视图实现,熟悉了组件的递归使用
代码如下:
let all={
name:'all',
children:{
A:{
name:'A',
children:{
a1:{
name:'a1',
children:{
a11:{
name:'a11',
children:null
},
a12:{
name:'a12',
children:null
}
}
},
a2:{
name:'a2',
children:{
b21:{
name:'b21',
children:null
}
}
}
}
},
B:{
name:'B',
children:{
b1:{
name:'b1',
children:{
b11:{
name:'b11',
children:null
},
b12:{
name:'b12',
children:null
}
}
},
b2:{
name:'b2',
children:{
b21:{
name:'b21',
children:null
}
}
}
}
}
}
}
代码如下
treelist.vue
代码如下:
<template>
<div>
<ul>
<li >
<span @click="isshow()">{{treelist.name}}</span>
<tree v-for="item in treelist.children"
v-if="isFolder"
v-show="open"
:treelist="item"
:keys="item"
></tree>
</li>
</ul>
</div>
</template>
<script>
export default {
name:'tree',
props:['treelist'],
data(){
return{
open:false
}
},computed:{
isFolder:function(){
return this.treelist.children
}
}
,methods:{
isshow(){
if (this.isFolder) {
this.open =!this.open
}
}
}
}
</script>
<style lang="less">
</style>
index.html
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>树形图</title>
</head>
<body>
<div id="app">
<tree :treelist="treeList"></tree>
</div>
</body>
</html>
index.js
代码如下:
import Vue from 'vue';
import tree from '../components/treelist.vue'
let all={
name:'all',
children:{
A:{
name:'A',
children:{
a1:{
name:'a1',
children:{
a11:{
name:'a11',
children:null
},
a12:{
name:'a12',
children:null
}
}
},
a2:{
name:'a2',
children:{
b21:{
name:'b21',
children:null
}
}
}
}
},
B:{
name:'B',
children:{
b1:{
name:'b1',
children:{
b11:{
name:'b11',
children:null
},
b12:{
name:'b12',
children:null
}
}
},
b2:{
name:'b2',
children:{
b21:{
name:'b21',
children:null
}
}
}
}
}
}
}
const app=new Vue({
el:"#app",
components:{
'tree':tree
},
data:{
treeList:all
}
})
在经过踩坑之后,我发现Vue官网有类似的案例,链接→ 传送门
参考过官网的方法后,我尝试着实现了一下
这样写和我踩坑时的 思路不同点在于, 这样一个组件只负责一个 对象,遍历每个children 中的对象,逐个传入组件处理,而我第一次尝试则是 将整个children 传入自身 是一个组件处理多个对象,(第一次尝试的失败案例,有兴趣请看最下方)
这样一个组件处理一个对象 写的好处是什么呢
我可以在组件内自定义开关了
我在data里定义了变量open,因为组件递归,所以相当于每个组件都有个属于自己的open
【图片暂缺】
那为什么第一次踩坑时我不可以用这种方法呢,因为我第一次尝试 是一个组件处理多个对象 就是相当于 一个开关控制 children中的所有对象,当开关打开时会导致 这个同级的所有 对象都被展开
遍历children 挨个传入组件自身 用v-show 来控制是否显示
【图片暂缺】
定义了一个计算属性,依据children来判断是否继续执行
【图片暂缺】
在span标签上绑定了一个自定义事件
更改open 的值
代码如下:
<span @click="isshow()">{{treelist.name}}</span>
【图片暂缺】
【图片暂缺】
以下 是我刚开始尝试的时候踩得坑
在这里记录一下,以后遇到类似问题留个印象
首先上来就遇到了这样的报错
【图片暂缺】
找了很久的问题,发现是因为组件内忘记写name了,自身使用自身必须填写name,并且与标签名一致
【图片暂缺】
一开始的实现方法,利用组件递归,显示出当前级的name渲染出来,并将其中的 children 中的所有对象 传给自己然后接着执行相同操作,直到children没有数据,值得一提的是
【图片暂缺】
,如果这里不加上 v-if 就会变成 死循环,就会一直执行下去,所以我们要判断一下当前执行的对象到底还有没有下一级
【图片暂缺】
这里我数据有稍微的改动,所以我第一次传入的数据就是(index.html页面)
【图片暂缺】
然后我定义了一个事件来处理 每一层的关闭和开启,我用弹框来查看Isopen 的值是否被改变
【图片暂缺】
我们看一下结果
刚进入页面时,括号中的undefined是 Isopen 当前的值,因为此时未被定义,所以为undefined
【图片暂缺】
然后我点击了A
【图片暂缺】
因为此时isopen已被反转值,所以此时isopen为true
【图片暂缺】
但是页面仍毫无变化,不说展开功能,就连undefined也没变化
【图片暂缺】
经过一番百度 ,发现原来是vue本身已经不允许这样直接更改 Props接受过来的值了
本文来自:http://www.q1010.com/184/4837-0.html
注:关于Vue 实现树形视图数据功能的内容就先介绍到这里,更多相关文章的可以留意四海网的其他信息。
关键词:vue.js
四海网收集整理一些常用的php代码,JS代码,数据库mysql等技术文章。