利用简单的树形视图实现,熟悉了组件的递归使用

这是模拟的树形图数据

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

Vue 实现树形视图数据功能

那为什么第一次踩坑时我不可以用这种方法呢,因为我第一次尝试 是一个组件处理多个对象 就是相当于 一个开关控制 children中的所有对象,当开关打开时会导致 这个同级的所有 对象都被展开

遍历children 挨个传入组件自身    用v-show 来控制是否显示 

Vue 实现树形视图数据功能

定义了一个计算属性,依据children来判断是否继续执行 

Vue 实现树形视图数据功能

在span标签上绑定了一个自定义事件

更改open 的值 

<span @click="isshow()">{{treelist.name}}</span>

Vue 实现树形视图数据功能

实现效果

Vue 实现树形视图数据功能

以下 是我刚开始尝试的时候踩得坑

在这里记录一下,以后遇到类似问题留个印象

首先上来就遇到了这样的报错

Vue 实现树形视图数据功能

找了很久的问题,发现是因为组件内忘记写name了,自身使用自身必须填写name,并且与标签名一致

Vue 实现树形视图数据功能

一开始的实现方法,利用组件递归,显示出当前级的name渲染出来,并将其中的 children 中的所有对象 传给自己然后接着执行相同操作,直到children没有数据,值得一提的是

Vue 实现树形视图数据功能

,如果这里不加上 v-if 就会变成 死循环,就会一直执行下去,所以我们要判断一下当前执行的对象到底还有没有下一级

Vue 实现树形视图数据功能

这里我数据有稍微的改动,所以我第一次传入的数据就是(index.html页面)

Vue 实现树形视图数据功能

然后我定义了一个事件来处理 每一层的关闭和开启,我用弹框来查看Isopen 的值是否被改变

Vue 实现树形视图数据功能

我们看一下结果

刚进入页面时,括号中的undefined是 Isopen 当前的值,因为此时未被定义,所以为undefined

Vue 实现树形视图数据功能

然后我点击了A

Vue 实现树形视图数据功能

因为此时isopen已被反转值,所以此时isopen为true

Vue 实现树形视图数据功能

但是页面仍毫无变化,不说展开功能,就连undefined也没变化

Vue 实现树形视图数据功能

经过一番百度 ,发现原来是vue本身已经不允许这样直接更改 Props接受过来的值了

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

华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。