写在前面
首先,本篇文章所开发的组件并非一个已经开源的上线组件,所以如果你急于需要一个插件来只做你的项目,那么并不能带给你及时的帮助。这个组件的开发预计写两篇文章,一遍写组件,一篇写组件逻辑。这篇文章也是我自己开发的从无到有的过程,所以它可以为你提供一些Tree组件开发的思路,代码写到一定程度,不能完全依赖插件了,有时间可以看看插件源码或者动手去开发,这样真的能加深对技术的掌握程度。
开发过程
1.数据仓库-Vuex
2.组件的循环创建-递归组件
需求决定了我的技术选型,项目需求是一个中国各级政府列表的选择,后台基于大数据去汇总各级政府网站的文章决策,然后交给前端去展示,左侧显示各级政府的Tree,右侧显示具体文章。因为政府数据的不确定性,所以显示政府的Tree的每一层级也是动态获取的,就比如北京市下级的海淀区政府在一小时前可能不存在某某政策文章,那么北京市节点的子节点中就不会包含海淀区这一子节点,但是10分钟前网站发布了一篇文章,那么就需要在北京市中添加海淀区,为了良好的实时性效果,每一级的子节点都不固定。
因此 树状结构的data是变化的而不是在初始化的时候就固定好 的,数据驱动Dom的思想,data有多少层级,Dom就有多少层级,data不定,所以Dom也无法提前定义好层级,决定采用Vue的递归组件,组件递归自身实现无限制层级的渲染。需求中每一个节点的Tree都具有增删改的功能,因为data是单例的,全局维护着一个data数据源头,增删改也就是操作data第n个子节点的某个子元素,因此采用了Vuex作为一个data存放的仓库( 这不是一个组件库,只是一个项目的应用 )。
项目的关键点:
1.动态加载子节点,也就是说页面加载的时候,根节点的 nodes 子节点数组可能是个空数组,每次单击节点去获取子节点数组。
2.全局单例的树节点对象 data 对象,每次得到新的子节点,需要去维护这个对象,因为数据与dom动态绑定,所以每次数据对象内部发生了变化,dom也会重绘。
vue对虚拟dom的映射通过使用diff算法进行了优化,所以不用担心,重绘造成页面闪屏
树 data 数据结构如下:
let data = { id: "01", lable: "政府机构", nodes: [ { id: "02", lable: "中央机关", nodes: [{ //.. }] }, { id: "03", lable: "直辖市", nodes: [{ //.. //北京市... //天津市.. }] }, ] };
显示成这样:
每一个节点包含id,label,nodes三个属性,nodes往下延伸子节点,一共有多少级不确定根据后台获取得到。
递归组件
一个简单的递归组件的示例如下:
<template> <div class="tree-menu"> //组件内部不断用自身,只要子节点存在就递归调用 <tree-menu v-for='(item, index) of dataNodes' :key='index'></tree-menu> </div> </template> <script> export default { name:'TreeMenu',//组件名称必须写 data() { return { dataNodes: { //... } } } } </script>
TreeMenu.vue声明组件TreeMenu,并向外暴露,在组件内部调用自身,也就是一个递归的思想,绑定的dataNodes有多少层级,那就会递归多少层,因为每一层都有v-for都会循环子节点。绑定具体数据的时候再具体分析。不断调用自身,当然这只是一个例子,实际情况还要改造一下:
新建TreeMenu.vue,作为显示节点的逻辑组件:
<template> <div class="tree-menu"> <div>{{label}}</div>//节点名称 <tree-menu //如果nodes.length>0就递归显示子节点 v-for="(node, index) of nodes" :key="index" :nodes="node.nodes" //子节点的子节点向下传递 :label="node.label" > </tree-menu> </div> </template> <script> export default { name: "TreeMenu", props:['label','nodes'],//数据通过pros向下传递,全局唯一数据源 data() { return {}; } }; </script>
创建Tree.vue作为节点树的入口:
<template> <div class="tree-alone"> <tree-menu :label="tree.label" :nodes="tree.nodes"></tree-menu> </div> </template> <script> import TreeMenu from './TreeMenu.vue' export default { name: 'tree', data() { return { tree: { id: "01", lable: "总层级", nodes: [ { id: "02", label: "层级1", nodes: [{ label: '层级1-1' }] }, { id: "03", label: "层级2", nodes: [] }, ] }; } } }, components: { TreeMenu } } </script>
在Tree.vue入口组件里引入子组件TreeMenu.vue,并且向子组件传递数据label和nodes,这里data先预定义一个简单的对象,后面会动态获取。
TreeMenu.vue作为树形菜单组件,负责递归和数据渲染,它会接受来自入口组件传递来的label和nodes数据,进行渲染, 并且继续递归传递nodes和label 。
在从父组件接收nodes和label后,先循环渲染n个tree-menu组件,然后每一个tree-menu又会递归自身,所以数据就这样一层层向下传递nodes=>nodes.node=>nodes.node.node,此时已经完成了数据与Dom的绑定,可以修改一下Tree.vue中的tree数据源,看一下组件是否动态改变了。现在渲染如下图:
数据正确渲染,现在需要加一些样式和点击事件(展开与收缩),就不做详细介绍了,代码如下: (向下传递depth参数来获取层级索引)
//Tree.vue <template> <div class="tree-alone"> <tree-menu :label="tree.label" :nodes="tree.nodes" :depth="0"></tree-menu> </div> </template> //TreeMenu.vue <template> <div class="tree-menu"> <div :style="indent" @click="toggleChildren">{{label}}</div> <div v-if="showChildren"> <tree-menu v-for="(item, index) of nodes" :key="index" :nodes="node.nodes" :label="node.label" :depth="depth + 1" ></tree-menu> </div> </div> </template> <script> export default { name: "TreeMenu", props: ["label", "nodes"], data() { return { showChildren: false }; }, methods: { toggleChildren() { this.showChildren = !this.showChildren; } }, computed: { indent() { return { transform: `translate(${this.depth * 20}px)` }; } } }; </script>
修改后会展开收缩与缩进,一些箭头旋转等样式问题就不详细写了。
总结
以上所述是小编给大家介绍的Vue递归组件+Vuex开发树形组件Tree--递归组件的简单实现,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍Vue2递归组件实现树形菜单,包括了Vue2递归组件实现树形菜单的使用技巧和注意事项,需要的朋友参考一下 今天看了老长时间递归组件,官方给的教程太简便了,根本看不出到底怎么用。于是自己查网摸索了一下,这儿只把核心思想写出来。 效果如下图,点击后打开二级菜单,再点击后打开三级。 由于每次递归组件,就相当于实例化了一次组件。所有写在组件data中的值都是该组件专属的。 树状结构: 我
本文向大家介绍vue递归组件实战之简单树形控件实例代码,包括了vue递归组件实战之简单树形控件实例代码的使用技巧和注意事项,需要的朋友参考一下 1、递归组件-简单树形控件预览及问题 在编写树形组件时遇到的问题: 组件如何才能递归调用? 递归组件点击事件如何传递? 2、树形控件基本结构及样式 3、组件目录及数据结构 目录结构 vue-tree VueTree.vue TreeItem.vue 树
本文向大家介绍vue 递归组件的简单使用示例,包括了vue 递归组件的简单使用示例的使用技巧和注意事项,需要的朋友参考一下 前言 递归 相信很多同学已经不陌生了,算法中我们经常用递归来解决问题。比如经典的:从一个全为数字的数组中找出其中相加能等于目标数的组合。思路也不难,循环数组取值,不断递归相加,直到满足目标数条件。递归虽然能解决大部分,但弊处在于,很容易写出死循环的代码,导致爆栈。下面以我实际
本文向大家介绍vuejs使用递归组件实现树形目录的方法,包括了vuejs使用递归组件实现树形目录的方法的使用技巧和注意事项,需要的朋友参考一下 上篇文章我提到了通讯录的开发,里面的目录使用了vue的递归组件实现的树形目录,这篇文章就来讲讲如何实现树形目录吧! 首先实现效果如下,觉得菜单还是比较nice的是吧: 这边数据调用的是数据库的数据的,需要数据库进行数据的构造,这里涉及到java的构造多叉树
本文向大家介绍Vue.js组件tree实现无限级树形菜单,包括了Vue.js组件tree实现无限级树形菜单的使用技巧和注意事项,需要的朋友参考一下 分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下。 代码看这里喽: html代码: js代码: 效果图: 本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。 关于vue.js组件的教程
本文向大家介绍开发Vue树形组件的示例代码,包括了开发Vue树形组件的示例代码的使用技巧和注意事项,需要的朋友参考一下 本文介绍了Vue树形组件的示例代码,分享给大家,具体如下: 使用SemanticUI和vue做一个menubar组件,实现方法大概是这样的: 使用时,假如父组件app使用到了menubar组件,那么data中需要定义一下items数据,例 : 里面的click事件是定义了,当在工