Vue.js 递归组件实现树形菜单
最近看了 Vue.js 的递归组件,实现了一个最基本的树形菜单。
main.js 作为入口:
import Vue from 'vue'
import main from './components/main.vue' new Vue({
el: '#app',
render: h => h(main)
})
它引入了一个组件 main.vue:
<template>
<div>
<my-tree :data="theData" :name="menuName" :loading="loading" @getSubMenu="getSubMenu"></my-tree>
</div>
</template> <script>
const myData = [
{
id: '1',
menuName: '基础管理',
menuCode: '10'
},
{
id: '2',
menuName: '商品管理',
menuCode: ''
},
{
id: '3',
menuName: '订单管理',
menuCode: '30',
children: [
{
menuName: '订单列表',
menuCode: '31'
},
{
menuName: '退货列表',
menuCode: '32',
children: []
}
]
},
{
id: '4',
menuName: '商家管理',
menuCode: '',
children: []
}
]; const subMenuData1 = {
parentId: '1',
children: [
{
menuName: '用户管理',
menuCode: '11'
},
{
id: '12',
menuName: '角色管理',
menuCode: '12',
children: [
{
menuName: '管理员',
menuCode: '121'
},
{
menuName: 'CEO',
menuCode: '122'
},
{
menuName: 'CFO',
menuCode: '123'
},
{
menuName: 'COO',
menuCode: '124'
},
{
menuName: '普通人',
menuCode: '124'
}
]
},
{
menuName: '权限管理',
menuCode: '13'
}
]
}; const subMenuData2 = {
parentId: '2',
children: [
{
menuName: '商品一',
menuCode: '21'
},
{
id: '22',
menuName: '商品二',
menuCode: '22',
children: [
{
menuName: '子类商品1',
menuCode: '221'
},
{
menuName: '子类商品2',
menuCode: '222'
}
]
}
]
}; import myTree from './common/treeMenu.vue'
export default {
components: {
myTree
},
data () {
return {
theData: myData,
menuName: 'menuName', // 显示菜单名称的属性
loading: false
}
},
methods: {
getSubMenu (menuItem, callback) {
this.loading = true; if (menuItem.id === subMenuData1.parentId) {
this.loading = false;
menuItem.children = subMenuData1.children;
callback(menuItem.children);
} setTimeout(() => {
if (menuItem.id === subMenuData2.parentId) {
this.loading = false;
menuItem.children = subMenuData2.children;
callback(menuItem.children);
}
}, 2000);
}
}
}
</script>
subMenuData1, subMenuData2 存放子菜单数据,可以从服务器获取,以实现动态加载。
该文件引入了树形组件 treeMenu.vue:
<template>
<ul class="tree-menu">
<li v-for="(item, index) in data">
<span @click="toggle(item, index)">
<i :class="['icon', item.children && item.children.length ? folderIconList[index] : 'file-text', loading ? loadingIconList[index] : '']"></i>
{{ item[name] || item.menuName }}
</span>
<tree-menu v-if="scope[index]" :data="item.children"></tree-menu>
</li>
</ul>
</template> <script>
export default {
name: 'treeMenu',
props: {
data: Array,
name: String,
loading: Boolean
},
data () {
return {
folderIconList: [],
loadingIconList: [],
scope: {}
}
},
created () {
this.data.forEach((item, index) => {
if (item.children && item.children.length) {
this.folderIconList[index] = 'folder';
}
});
},
methods: {
doTask (index) {
this.$set(this.scope, index, !this.scope[index]);
this.folderIconList[index] = this.scope[index] ? 'folder-open' : 'folder';
},
toggle (item, index) {
this.loadingIconList = []; if (item.children && item.children.length) {
this.doTask(index);
} else {
this.loadingIconList[index] = 'loading'; this.$emit('getSubMenu', item, (subMenuList) => {
if (subMenuList && subMenuList.length) {
this.doTask(index);
}
});
}
}
}
}
</script> <style scoped>
.tree-menu {
list-style: none;
}
.tree-menu li {
line-height: 2;
}
.tree-menu li span {
cursor: default;
}
.icon {
display: inline-block;
width: 15px;
height: 15px;
background-repeat: no-repeat;
vertical-align: -2px;
}
.icon.folder {
background-image: url(/src/assets/folder.png);
}
.icon.folder-open {
background-image: url(/src/assets/folder-open.png);
}
.icon.file-text {
background-image: url(/src/assets/file-text.png);
}
.icon.loading {
background-image: url(/src/assets/loading.gif);
background-size: 15px;
}
</style>
效果图:

示例代码放在这里。
Vue.js 递归组件实现树形菜单的更多相关文章
- 【Vue.js实战案例】- Vue.js递归组件实现组织架构树和选人功能
大家好!先上图看看本次案例的整体效果. 浪奔,浪流,万里涛涛江水永不休.如果在jq时代来实这个功能简直有些噩梦了,但是自从前端思想发展到现在的以MVVM为主流的大背景下,来实现一个这样繁杂的功能简直不 ...
- Vue.js递归组件实现动态树形菜单
使用Vue递归组件实现动态菜单 现在很多项目的菜单都是动态生成的,之前自己做项目也是遇到这种需求,翻看了官网案例,和网上大神的案例.只有两个感觉,官网的案例太简洁,没有什么注释,看起来不太好理解,大神 ...
- 用Vue.js递归组件构建一个可折叠的树形菜单
在Vue.js中一个递归组件调用的是其本身,如: Vue.component('recursive-component', { template: `<!--Invoking myself! ...
- vue的递归组件以及三级菜单的制作
js里面有递归算法,同时,我们也可以利用props来实现vue模板的递归调用,但是前提是组件拥有 name 属性 父组件:slotDemo.vue: <template> <div& ...
- vue之递归组件实现树形目录
递归组件的应用===>可以通过组件命名来自己使用自己的组件 实例如下 父组件 <div class="content"> <detail-list :lis ...
- 【Vue课堂】Vue.js 父子组件之间通信的十种方式
这篇文章介绍了Vue.js 父子组件之间通信的十种方式,不管是初学者还是已经在用 Vue 的开发者都会有所收获.无可否认,现在无论大厂还是小厂都已经用上了 Vue.js 框架,简单易上手不说,教程详尽 ...
- 谈谈Vue的递归组件
2月最后一天,而且还四年一遇,然而本月居然一篇博客没写,有点说不过去.所以,今天就来谈谈Vue的递归组件.我们先来看一个例子: See the Pen 递归组件 by imgss (@imgss) o ...
- Vue.js多重组件嵌套
Vue.js多重组件嵌套 Vue.js中提供了非常棒的组件化思想,组件提高了代码的复用性.今天我们来实现一个形如 <app> <app-header></app-head ...
- Vue.js之组件传值
Vue.js之组件传值 属性传值可以从父组件到子组件,也可以从子组件到父组件. 这里讲一下从父组件到子组件的传值 还以上次的demo为例,demo里有APP.vue是父组件,Header.vue,Us ...
随机推荐
- 判断手机端用户打开页面时是android还是ios,并将判断结果通过ajax返回给url接口,传递回去
首先判断页面是android还是ios,然后利用ajax将结果通过接口url返回回去,记录到log日志中,以统计android和ios用户访问该页面的数量(数据统计) <script type= ...
- Design7:数据删除设计
在设计一个新系统的Table Schema的时候,不仅需要满足业务逻辑的复杂需求,而且需要考虑如何设计schema才能更快的更新和查询数据,减少维护成本. 模拟一个场景,有如下Table Schema ...
- ExtJs4之Grid详细
ExtJs博客前奏 由于这段时间事情比较杂乱,博客就主要以项目中例子来说明编写. ExtJs4中的Grid非常强大,有展示,选中,搜索,排序,编辑,拖拽等基本功能,这篇博客我就这几个功能做写累述. 1 ...
- Unity3D研究院之Prefab里面的Prefab关联问题
最近在做UI部分中遇到了这样的问题,就是Prefab里面预制了Prefab.可是在Unity里面一旦Prefab预制了Prefab那么内部的Prefab就失去关联.导致与如果要改内部的Prefab需要 ...
- 【转】WPF防止界面卡死并显示加载中效果
原文地址:http://www.cnblogs.com/linyijia/archive/2013/02/06/2900609.html <Window x:Class="Loadin ...
- JavaScript使用构造函数获取变量的类型名
在JavaScript中,如何准确获取变量的类型名是一个经常使用的问题. 但是常常不能获取到变量的精确名称,或者必须使用jQuery 中的方法,这里 我通过 typeof ,jQuery.type 和 ...
- PHP中MySQL操作
本次使用的demo是MySQL的示例数据库employees,点击下载地址,注意在导入的时候,在employees.sql文件中,将source改成你当前的目录. PHP中的demo代码可以在ideo ...
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
- CloudNotes之桌面客户端篇:增强的笔记列表
今天,我发布了CloudNotes的一个更新版本:1.0.5484.36793.这个版本与1.0.5472.20097不同的是,它拥有增强的笔记列表,与之前单调的列表系统相比,新的笔记列表不仅可以显示 ...
- 【Basics of Entity Framework】【EF基础系列1】
EF自己包括看视频,看MSDN零零散散的学了一点皮毛,这次打算系统学习一下EF.我将会使用VS2012来学习这个EF基础系列. 现在看看EF的历史吧: EF版本 相关版本特性介绍 EF3.5 基于数据 ...