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()进行响应更改

(0)

相关推荐

  • Vue.js 递归组件实现树形菜单(实例分享)

    最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单. 项目结构: main.js 作为入口,很简单: import Vue from 'vue' Vue.config.debug = true import main from './components/main.vue' new Vue({ el: '#app', render: h => h(main) }) 它引入了一个组件 main.vue: <template> <div class="tree-m

  • 基于 Vue 的树形选择组件的示例代码

    本文介绍了基于 Vue 的树形选择组件.分享给大家,具体如下: 系统要求:Vue 2 基本特性 完美的多级联动效果 支持无限多的分级 有 全选.半选.不选 三种状态  截图展示 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="icon" href="https://v1-c

  • vuejs使用递归组件实现树形目录的方法

    上篇文章我提到了通讯录的开发,里面的目录使用了vue的递归组件实现的树形目录,这篇文章就来讲讲如何实现树形目录吧! 首先实现效果如下,觉得菜单还是比较nice的是吧: 这边数据调用的是数据库的数据的,需要数据库进行数据的构造,这里涉及到java的构造多叉树的知识,后续我会另外写一篇文章详细讲解,这里讲下前端. 数据可以先构造json使用,这里用到的格式大概如下,以childList来嵌套子菜单: { id:YH, name:银行, pid:0, childList:[{ id:YH******,

  • Vue2递归组件实现树形菜单

    今天看了老长时间递归组件,官方给的教程太简便了,根本看不出到底怎么用.于是自己查网摸索了一下,这儿只把核心思想写出来. 效果如下图,点击后打开二级菜单,再点击后打开三级. //js //引子 //思想:当v-if='false'时,循环时进行的.所以一开始就设置为false. ggg:{ name:'gs', template:` <div> <p @click.stop='show=!show'>我是p标签</p> //这儿show必须要初始值为false,不然就是堆

  • Vue.js组件tree实现无限级树形菜单

    分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下. 代码看这里喽: html代码: <div class="tree"> <nav class='navbar'> <ul class='nav nav-stacked'> <template v-for='item in menus'> <li role='presentation' v-if='!item.c

  • VUE饿了么树形控件添加增删改功能的示例代码

    本文介绍了VUE饿了么树形控件添加增删改功能的示例代码,分享给大家,具体如下: element-ui树形控件:地址 在原文档中有个案例是有新增和删除功能,但是后来发现其修改的数据并不能直接影响到树形数据,所以采用了 render-content 的API重新写了个组件. 写个开发的步骤,所以文章比较长emmm 大致效果如图: 1.省市API 在网上复制了个省市的list,有两个属性是新增的 isEdit :控制编辑状态 maxexpandId :为现下id的最大值 export default{

  • Vue组件tree实现树形菜单

    vue 编写的树形菜单,小巧实用,支持vue1.0,vue2.0 v1.0 功能: 1.支持多级树目录 2.支持高亮点击的节点 3.支持展开点击节点 4.支持点击收缩节点时收缩所有子目录 5.支持自定义回调函数,点击节点时回调,参数为节点信息 用法:<launch-tree :list='list' :options='options'></launch-tree> list = [ { name: '一级目录', // 目录名字 isOpen: true, // 是否初始展开目录

  • 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:nul

  • 基于Vue实现tab栏切换内容不断实时刷新数据功能

    先说一下产品需求,就是有几个tab栏,每个tab栏对应的ajax请求不一样,内容区域一样,内容为实时刷新数据,每3s需要重新请求,返回的数据在内容区域展示,每点击一次tab栏需停止其他tab栏ajax请求,防止阻塞,首次加载页面的时候又不能5个ajax同时请求,只需要请求第一个就好 也没有必要建立5个区域,控制显示隐藏,浪费性能,业务代码就不贴了,把大概原理的代码贴上来 先是用jq实现了一版 <!DOCTYPE html> <html lang="en"> &l

  • 详解vue模拟加载更多功能(数据追加)

    使用vue制作加载更多功能,通过ajax获取的数据往data里面push经常不成功,原因是push是往数组中追加数据内容的,而不能用作数组之间的拼接,ajax获取的数据就是数组形式的,因此不成功,应该使用concat()拼接两个数组. //这是错误的写法 $.ajax({ type:'get', async:false, url:path+'no/noticeMobile/getSendNoticeList?imToken='+ getToken +'&pageFlag=2', dataType

  • vue实现树形结构样式和功能的实例代码

    一.主要运用element封装的控件并封装成组件运用,如图所示 代码如图所示: 下面是子组件的代码: <template> <ul class="l_tree"> <li class="l_tree_branch" v-for="item in model" :key="item.id"> <div class="l_tree_click"> <butt

  • vue+vuex+json-seiver实现数据展示+分页功能

    一丶项目分析 1.UI: 2.接口信息: 二丶项目环境 Mockjs:生成模拟数据(含中文名,以及地址) json-server:模拟后端接口 webpack-dev-server:开启服务器环境+接口代理 jquery:使用jquery的ajax拉取数据 vue+vuex:vuex负责数据交互,vue渲染页面 iviewui:ui组件,方便布局 搭建开发环境 1.基本环境 Vue起步(无cli) 安装: npm install --save Mockjs 使用: 详细API:mockjs.co

  • 解决vue中修改了数据但视图无法更新的情况

    我们有时候常碰到vue中明明修改了数据,但是视图无法更新,因此我总结了一点点碰到此类的情况: 1.v-for遍历的数组,当数组内容使用的是arr[0].xx =xx更改数据,vue无法监测到 数组数据变动:我们使用某些方法操作数组,变动数据时,有些方法无法被vue监测,有些可以 Vue包装了数个数组操作函数,使用这些方法操作的数组去,其数据变动时会被vue监测: push() pop() shift() unshift() splice() sort() reverse() vue2.0还增加个

  • Vue mock.js模拟数据实现首页导航与左侧菜单功能

    目录 一.mock.js的使用 mock.js的使用步骤 1.安装mock依赖 2.添加开发环境及生产环境的配置 3.引入到main.js 二.前台主页面的搭建 2.1 准备相关组件 2.2 配置路由与组件的关系 2.3 导入图片 2.4 测试 三.左侧菜单的收缩功能 3.1 定义一个总线 3.2 改变收缩图标的样式 四.退出功能 4.1 添加点击方法 4.2 测试 一.mock.js的使用 mock.js的使用步骤 ① 下载依赖 npm install mock -d(开发环境使用) ② 引入

  • Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一)

    环境搭建 spring boot的简介 以往我们开发时用到spring总是避免不了繁琐的配置,例如我们要配置一个数据库连接,可能需要以下几步: 1.编写jdbc.properties配置文件: 2.创建spring的配置文件,加入spring配置文件前缀.配置数据库连接信息以及sqlsessionFactory等等: 3.还要在web.xml文件中加入spring的监听. springboot的出现大大简化了项目的搭建过程(spring配置以及maven配置),让我们专注于应用功能的开发,而不是

  • vue中axios实现数据交互与跨域问题

    1. 通过axios实现数据请求 vue.js默认没有提供ajax功能的. 所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互. 注意,axios本质上就是javascript的ajax封装,所以会被同源策略限制. 下载地址: https://unpkg.com/axios@0.18.0/dist/axios.js https://unpkg.com/axios@0.18.0/dist/axios.min.js axios提供发送请求的常用方法有两个:axio

  • 浅析Vue中拆分视图层代码的5点建议

    一.框架的定位 框架通常只是一种设计模式的实现,它并不意味着你可以在开发中避免所有分层设计工作. SPA 框架几乎都是基于 MVC 或 MVVM 设计模式而建立起来的,这些模式都只是宏观的分层设计,当代码量开始随着项目增大而增多时,问题就会越来越多.许多企业内部的项目仍然在使用 angularjs1.X ,你会发现许多 controller 的体积大到令人发指,稍有经验的团队会利用好 angularjs1 构建的 controller , service , filter 以及路由和消息机制来完

随机推荐