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 ...
随机推荐
- SQL 数据库管理---公司培训
一.实例 一个SQL的服务引擎就是一个SQL实例,每装一次SQL就会产生一次实例. 实例分为命名实例和默认实例,一台Windows服务器可以有多个SQL实例,但是只能有一个默认实例. 不同的实例之间相 ...
- python利用dict模拟switch
pytho本身并未提供switch语句,但可以通过dict来模拟switch, #方法1 def add(x,y): return x+y def dec(x,y): return x-y def m ...
- Java多线程系列目录(共43篇)
最近,在研究Java多线程的内容目录,将其内容逐步整理并发布. (一) 基础篇 01. Java多线程系列--“基础篇”01之 基本概念 02. Java多线程系列--“基础篇”02之 常用的实现多线 ...
- 项目中遇到的Integer问题--转
Integer类型值相等或不等分析 http://www.cnblogs.com/zzllx/p/5778470.html 看到博客园一位博友写的面试问题,其中一题是 Integer a = 1; I ...
- 【Java】 环境变量如何配置?
Java知识简介与环境变量配置问题 一.在学习一门语言中,不仅需要掌握其语法结构,开发平台以及环境也是很重要的.在开始Java学习之前首先对其进行压缩包的下载安装,以及开发平台环境下载安装.基于此下面 ...
- Oracle Database Server 'TNS Listener'远程数据投毒漏洞(CVE-2012-1675)解决
环境:Windows 2008 R2 + Oracle 10.2.0.3 应用最新bundle patch后,扫描依然报出漏洞 Oracle Database Server 'TNS Listener ...
- selenium操作隐藏的元素
有时候我们会碰到一些元素不可见,这个时候selenium就无法对这些元素进行操作了.例如,下面的情况: Python 页面主要通过“display:none”来控制整个下拉框不可见.这个时候如果直接操 ...
- struts2学习笔记--struts.xml配置文件详解
这一节主要讲解struts2里面的struts.xml的常用标签及作用: 解决乱码问题 <constant name="struts.i18n.encoding" value ...
- OpenCV2:Mat属性type,depth,step
在OpenCV2中Mat类无疑使占据着核心地位的,前段时间初学OpenCV2时对Mat类有了个初步的了解,见OpenCV2:Mat初学.这几天试着用OpenCV2实现了图像缩小的两种算法:基于等间隔采 ...
- 【406错误】 The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
今天遇到一个奇怪的错误,关于Springmvc的,我明明在Controller方法中写了@ResponseBody,返回一个Map,结果报了406错误. 结果发现,少了一个jar包: 加上去就没事了.