vue 递归组件多级_Vue 递归组件构建一个树形菜单
原标题:Vue 递归组件构建一个树形菜单
Vue.js 中的递归组件是一个可以调用自己的组件例如:
Vue.component('recursive-component', {
template: ``
});
递归组件一般用于博客上显示评论,树形菜单或者嵌套菜单。
一、初始化
我们直接使用 vue 提供的脚手架 vue-cli 来初始化我们的工程:
# 搭建项目
vue init webpack-simple tree-menu
# 进入项目
cd tree-menu
# 依赖安装
npm install
# 运行项目
npm run dev
现在我们的环境已经准备好了,在初始化的项目中,有一些不需要的代码我们可以自己动手删除。
二、数据结构
在本教程中,我们将使用一个树结构的数据来作为我们的每个菜单项,其中每个节点都是一个对象:
label 属性,作为菜单的列表,如果该菜单下还有子菜单,就需要一个 nodes 属性,这是一个或多个节点的数组。
这里需要注意的是像所有的树结构一样,必须有一个根节点,然后从这个根节点进行无限嵌套。
let tree = {
label: 'root',
nodes: [
{
label: 'item1',
nodes: [
{
label: 'item1.1'
},
{
label: 'item1.2',
nodes: [
{
label: 'item1.2.1'
}
]
}
]
},
{
label: 'item2'
}
]
}
三、递归组件
将 src 下的 app.vue 修改为 TreeMenu.vue ,该组件将作为我们的树形的递归组件,用来显示当前节点和自己的子节点。
v-for="node in nodes"
:nodes="node.nodes"
:label="node.label"
>
<>
export default {
props: [ 'label', 'nodes' ],
name: 'tree-menu'
}
>
如果您正在使用递归组件,则必须使用全局注册 Vue.component,或者给它一个 name 属性。否则,组件的任何子节点将无法解析进一步的调用,并且会得到未定义的组件错误。
和任何递归函数一样,我们需要一个条件来结束递归,否则渲染将无限期地继续下去,最终会导致堆栈溢出。
在我们的树形菜单中,当我们到达一个没有子节点的节点时,我们想要停止递归。你可以用 v-for ,如果 nodes 数组未定义,tree-menu 则不会继续调用组件。
...
四、主模块
在主模块 main.js 中声明一个树形结构的数据,并将该数据作为 data 属性的值,并引入 TreeMenu 组件 。
/* ./src/main.js */
import TreeMenu from './TreeMenu.vue'
let tree = {
...
}
new Vue({
el: '#app',
data: {
tree
},
components: {
TreeMenu
}
})
由于我们的数据结构只有一个单一的根节点。为了开始递归,我们将 TreeMenu 组件作为根节点的子节点,修改根目录下的 index.html 文件:
五、缩进
为了让用户可以直观地识别子组件,就有必要对每一层的子节点进行缩进。为了实现该效果,我们通过添加一个 depth 来实现。使用这个值来动态设置 css 中的 transform 属性,从而实现缩进效果。
v-for="node in nodes"
:nodes="node.nodes"
:label="node.label"
:depth="depth + 1"
>
<>
export default {
props: [ 'label', 'nodes', 'depth' ],
name: 'tree-menu',
computed: {
indent() {
return { transform: `translate(${this.depth * 50}px)` }
}
}
}
>
同时在 index.html 上将 depth 设置为从零,也就是初始的时候是没有缩进的。这样每次将该值传递给任何子节点时,该值都会增加。
:label="tree.label"
:nodes="tree.nodes"
:depth="0"
>
注意:depth 的值要确保它是一个 Java 数字而不是一个字符串。
六、收缩
在初始的时候,应该只显示根节点,其他节点全部隐藏,然后通过鼠标点击的时候,能够展开各个节点。
为此,我们将添加一个本地状态 showChildren 。如果该值为 false,则不显示子节点,如果为 true 则显示子节点。而这个值应该通过鼠标点击节点来进行切换,所以我们需要一个点击事件:
v-if="showChildren"
v-for="node in nodes"
:nodes="node.nodes"
:label="node.label"
:depth="depth + 1"
>
<>
export default {
props: [ 'label', 'nodes', 'depth' ],
data() {
return { showChildren: false }
},
name: 'tree-menu',
computed: {
indent() {
return { transform: `translate(${this.depth * 50}px)` }
}
},
methods: {
toggleChildren() {
this.showChildren = !this.showChildren;
}
}
}
>
七、样式
经过以上步骤就已经完成了一个基本的树形菜单。为了使 UI 效果更佳,我们可以添加一个加号和减号图标,使用户界面更加明显。以下是全部的代码:
:label="tree.label"
:nodes="tree.nodes"
:depth="0"
>
/* ./src/main.js */
import Vue from 'vue'
import TreeMenu from './TreeMenu.vue'
import './assets/app.css'
//定义树形菜单数据
let tree = {
label: 'root',
nodes: [
{
label: 'item1',
nodes: [
{
label: 'item1.1'
},
{
label: 'item1.2',
nodes: [
{
label: 'item1.2.1'
}
]
}
]
},
{
label: 'item2'
}
]
}
new Vue({
el: '#app',
// render: h => h(App)
data: {
tree
},
components: {
TreeMenu
}
})
{{ label }}
v-if="showChildren"
v-for="node in nodes"
:nodes="node.nodes"
:label="node.label"
:depth="depth + 1"
>
<>
export default {
props: [ 'label', 'nodes', 'depth' ],
name: 'tree-menu',
data() {
return { showChildren: false }
},
computed: {
iconClasses: function iconClasses() {
return {
'plus': !this.showChildren,
'minus': this.showChildren
};
},
labelClasses: function labelClasses() {
return { 'has-children': this.nodes };
},
indent() {
return { transform: `translate(${this.depth * 50}px)` }
}
},
methods: {
toggleChildren() {
this.showChildren = !this.showChildren;
}
}
}
>
./src/assets/app.css
body {
font-family: sans-serif;
font-size: 18px;
font-weight: 300;
line-height: 1em;
}
.container {
width: 300px;
margin: 0 auto;
}
.tree-menu .label-wrapper {
padding-bottom: 10px;
margin-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.tree-menu .label-wrapper .has-children {
cursor: pointer;
}
.plus:before {
content:'+';
}
.minus:before {
content:'-';
}
本文章由源码时代H5学科讲师原创!
转载须注明出处(http://www.itsource.cn)!感谢大家的配合!返回搜狐,查看更多
责任编辑:
vue 递归组件多级_Vue 递归组件构建一个树形菜单相关推荐
- vue 递归组件多级_Vue递归组件实现树形结构菜单
Tree 组件是递归类组件的典型代表,它常用于文件夹.组织架构.生物分类.国家地区等等,世间万物的大多数结构都是树形结构.使用树控件可以完整展现其中的层级关系,并具有展开收起选择等交互功能. 如图所示 ...
- vue 组件数据共享_Vue共享组件
vue 组件数据共享 As a company, we sell experiences on many different sales channels, gotui.com, musement.c ...
- vue 父链和子组件索引_vue子组件和父组件双向绑定的几种方案
v-model案例 模仿v-model实现案例 我是一串要和内部名字联动的一串文字(父组件) 父组件改变值带动(父组件)点一下试试 .sync方案实现案例 这是父组件的东西.利用这个框改变值,看看有没 ...
- vue 父组件调子组件方法_vue父组件调用子组件有哪些方法
这次给大家带来vue父组件调用子组件有哪些方法,vue父组件调用子组件的注意事项有哪些,下面就是实战案例,一起来看一下. 情景: 父组件中引入上传附件的子组件:点击组件可以分别上传对应要求的图片,子组 ...
- vue 圆形百分比进度条_快速构建一个圆形的进度条
在一些特别生的网站上,用户需要一个可视化的是示,以表明网站资源仍然在加载.从Spinner到Skeleton屏幕有不同的方法来解决这类的用户体验效果. 如果我们使用的是开箱即用的解决方案,它为我们提供 ...
- vue 获取当前路由_VUE 在组件中 获取 路由信息
一.核心代码 1.获取参数 this.$route.query.id this.$route.query 2.页面跳转 登录 3.方法跳转 this.$router.push({ path: '/lo ...
- 子组件调用父组件方法_vue父子组件通信以及非父子组件通信的方法
组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.一般来说,组件可以有以下几种关系,父子关系.兄弟关系和隔代关系,简化点可以分为父子关系和 ...
- python三级联动菜单_VUE+element三级联动或树形菜单获取最后一项,并加入到表格中...
如下图,要实现的功能如下,勾选三级联动的材料,勾选最后一级的材料,把勾选的材料信息动态添加到下面表格中 1 data数据 return { options:[], // 三级联动 数据 options ...
- Vue封装树形菜单组件
csdn终于更新完成了哈,ok,步入正题 像这种树形结构的核心思想就是:递归思想,知道使用递归,其实这个例子函数的封装也就很简单喽 实现步骤: 设置的props: ...
最新文章
- 软件性能测试瓶颈定位,软件性能问题正确定位思路
- java while do_java中while和do-while的总结
- vue自动提交表单_(尚012)Vue表单数据的自动手集(表单数据提交,需要收集表单数据)...
- 电动车爬坡时究竟应该用最快档还是用最慢档?
- 数据分析 | 这个新职业年薪高达49w,作为普通打工人的你眼馋了吗?
- HDOJ1005(找循环节点)
- 拉格朗日插值编程实现
- zookeeper集群节点热扩容和迁移详解
- 20130331java语言基础学习笔记-语句_breakcontinue
- 单片机毕业设计 超声波雷达可视化系统
- 【研发管理】质量管理之约瑟夫·M.朱兰
- linux系统设置中文
- 四年的自学,通过这些学习工具拿到了大厂offer,分享给大家
- 修路【NOIP2016提高组模拟】
- 解决支付订单,重复提交问题!
- appiume连接逍遥模拟器
- 金九银十,测试思维面试题最新整理
- Thread.currentThread()方法 Runnable
- 行通信比并行通信的速度更高
- java代理一(静态代理)