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 ...
随机推荐
- Windows无法安装到这个磁盘。请确保在计算机的BIOS菜单中启用了磁盘控制器
今天一朋友问我这个问题,呃,以前我也遇到过,但忘记记录了,这次就记录一下吧,就懒得打字了,图片里面很清楚了 不说点什么的话是不是太水了O(∩_∩)O~,好吧扩充一下: Windows无法安装到这个磁盘 ...
- JS动态生成的元素,其对应的方法不响应(比如单击事件,鼠标移动事件等)
主要原因:在页面给元素注册点击事件的时候[ $(function () { XXX }); ],JS动态生成的元素还尚未生成,所以click事件就没有生效 解决方法: 方案一:js动态生成元素后再给 ...
- 前端学PHP之语句
× 目录 [1]if语句 [2]switch [3]while[4]do-while[5]for语句[6]foreach[7]break[8]continue[9]goto 前面的话 任何 PHP 脚 ...
- Android之JSON解析
做个Android网络编程的同学一定对于JSON解析一点都不陌生,因为现在我们通过手机向服务器请求资源,服务器给我们返回的数据资源一般都是以JSON格式返回,当然还有一些通过XML格式返回,相对JSO ...
- Android音频开发之AudioRecord录音实现
前言: 其实在Android中录音可以用MediaRecord录音,操作比较简单.但是不能对音频进行处理.考虑到项目中做的是实时语音只能选择AudioRecord进行录音. 本文算是对AudioRec ...
- 使用VS Code开发ASP.NET 5 应用程序
本文简要地翻译了 https://code.visualstudio.com/Docs/runtimes/ASPnet5 并结合我的实践做了一些说明. 准备工作 1.安装VS Code https: ...
- MySQL常见错误
1. TokuFT file system space is really low and access is restricted 解决方法:修改tokudb_fs_reserve_percent参 ...
- Windows 10 技术预览版9926 “未知源”引起系统休眠后自启的解决办法
问题的由来: 自从安装上了最新发布的Windows 10 ,使用起来有诸多的改进:无论是重绘的图标还是通知消息中心的整合还是更智能的OneDrive客户端都使得工作起来非常愉悦. 不过笔者这两天频繁遇 ...
- 【Java心得总结五】Java容器上——容器初探
在数学中我们有集合的概念,所谓的一个集合,就是将数个对象归类而分成为一个或数个形态各异的大小整体. 一般来讲,集合是具有某种特性的事物的整体,或是一些确认对象的汇集.构成集合的事物或对象称作元素或是成 ...
- Kooboo CMS 无聊随笔 (1)
因为公司的框架不开源,但是自己一直都有研究框架的兴趣,所以拿了一个开源的框架过来,而这个开源的框架就是Kooboo CMS.首先我无法用言语来形容我对这个CMS的赞美之词了,总之大家知道一点,这个CM ...