Vue 实现树形视图数据功能

 更新时间:2018年05月07日 11:52:34   作者:倪晓磊  
这篇文章主要介绍了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接受过来的值了

Vue2.0以后子组件不能更改父组件的值,只能通过子组件$emit(),父组件$on()进行响应更改

相关文章

  • vue ElementUI级联选择器回显问题解决

    vue ElementUI级联选择器回显问题解决

    这篇文章主要介绍了vue ElementUI级联选择器回显问题解决,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • ElementUI radio组件选中小改造

    ElementUI radio组件选中小改造

    这篇文章主要介绍了ElementUI radio组件选中小改造,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • vue3 自定义指令控制按钮权限的操作代码

    vue3 自定义指令控制按钮权限的操作代码

    这篇文章主要介绍了vue3 自定义指令控制按钮权限,为了提高用户体验,当该按钮无权使用时,使用el-tooltip功能进行提醒,结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • vue:内存泄露详解

    vue:内存泄露详解

    这篇文章主要介绍了一个Vue的内存泄露详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-10-10
  • 详解el-table表头文字换行的三种方式

    详解el-table表头文字换行的三种方式

    本文主要介绍了el-table表头文字换行的三种方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Vue实现6位数密码效果

    Vue实现6位数密码效果

    这篇文章主要为大家详细介绍了Vue实现6位数密码,优化iOS WebView卡顿,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • configureWebpack、chainWebpack配置vue.config.js方式

    configureWebpack、chainWebpack配置vue.config.js方式

    这篇文章主要介绍了configureWebpack、chainWebpack配置vue.config.js方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • vue中Axios的封装和API接口的管理示例详解

    vue中Axios的封装和API接口的管理示例详解

    这篇文章主要介绍了vue中Axios的封装和API接口的管理,主要目的就是在帮助我们简化代码和利于后期的更新维护,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • 用Vue.js在浏览器中实现裁剪图像功能

    用Vue.js在浏览器中实现裁剪图像功能

    在本教程中,我们将探讨如何在浏览器中使用 JavaScript 库来操作图片,为服务器上的存储做准备,并在 Web 程序中使用。我们将使用 Vue.js 而不是原生 JavaScript来完成此操作,需要的朋友可以参考下
    2019-06-06
  • 解决vue-router进行build无法正常显示路由页面的问题

    解决vue-router进行build无法正常显示路由页面的问题

    下面小编就为大家分享一篇解决vue-router进行build无法正常显示路由页面的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论