Vue通过递归实现多级菜单展示
1、模拟后台返回的菜单JSON数据如下data.json文件{"data": {"router": [{"path": "","name": "Home","component": "Layout","r...
·
1、模拟后台返回的菜单JSON数据如下data.json文件
{
"data": {
"router": [
{
"path": "",
"name": "Home",
"component": "Layout",
"redirect": "dashboard",
"children": [
{
"path": "dashboard",
"name": "Home",
"component": "dashboard/index",
"meta": {
"title": "首页",
"icon": "dashboard"
}
}
]
},
{
"path": "/example",
"component": "Layout",
"redirect": "/example/table",
"name": "Example",
"meta": {
"title": "案例",
"icon": "example"
},
"children": [
{
"path": "table",
"name": "Table",
"component": "table/index",
"meta": {
"title": "表格",
"icon": "table"
}
},
{
"path": "tree",
"name": "Tree",
"component": "tree/index",
"meta": {
"title": "树形菜单",
"icon": "tree"
}
}
]
},
{
"path": "/form",
"name": "Form",
"component": "Layout",
"children": [
{
"path": "index",
"name": "Form",
"component": "form/index",
"meta": {
"title": "表单",
"icon": "form"
},
"children": [
{
"path": "index",
"name": "Row",
"component": "form/index",
"meta": {
"title": "行",
"icon": "form"
}
},
{
"path": "index",
"name": "Col",
"component": "form/index",
"meta": {
"title": "列",
"icon": "form"
}
}
]
}
]
}
]
}
}
2、模拟接口取json文件数据,如下mock.js
import Mock from 'mockjs'
const MenuList=require('./data.json');
//获取菜单模块
Mock.mock('/api/getMenuList', (req, res) => {
return {
"result": "success",
"data": MenuList,
"msg": "获取成功"
}
});
3、定义接口文件api.js,调用mock中的接口,抛出接口
import axios from './http'; // 导入http中创建的axios实例
const api = {
getMenuList(params) {
return axios.post('/api/getMenuList', JSON.stringify(params));
},
}
export default api;
4、home组件
<template>
<el-aside>
<Menu :list="listData"></Menu>
</el-aside>
</template>
<script>
import Menu from "./Menu.vue";
export default {
name: "home",
components: {
Menu
},
data() {
return {
listData: []
};
},
mounted() {
this.getData();
},
methods: {
//获取菜单列表数据
getData: function() {
let that = this;
this.$api.getMenuList().then(res => {
let result = res.data;
that.listData = result.data.data.router;
});
}
}
};
</script>
效果如下:
5、Menu组件定义
<template>
<ul class="wrapper">
<MenuItem :key="index" v-for="(item, index) in list">
<span v-if="item.children">
<span @click="handleToggleShow" class="item-title">{{item.name}}</span>
<Menu :list="item.children" v-if="toggleShow"></Menu>
</span>
<template v-else>
<span>{{item.name}}</span>
</template>
</MenuItem>
</ul>
</template>
<script>
import MenuItem from "./MenuItem";
export default {
name: "Menu",
props: ["list"], //Menu组件接受一个list作为菜单数据
components: { MenuItem },
data() {
return {
toggleShow: false //子菜单是否显示
};
},
methods: {
handleToggleShow() {
this.toggleShow = !this.toggleShow;
}
}
};
</script>
<style lang="stylus" scoped>
.wrapper {
cursor: pointer;
.item-title {
font-size: 16px;
font-weight: bold;
}
}
</style>
6、MenuItem组件定义
<template>
<li class="item">
<slot />
</li>
</template>
<style lang="stylus" scoped>
.item {
margin: 10px 0;
padding: 10px;
border-radius: 4px;
list-style: none;
background: red;
color: #fff;
}
</style>
7、main.js全局引入注册
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
// 引入axios
import axios from 'axios';
// 挂载到vue原型链上
Vue.prototype.axios = axios;
// 引入api接口
import api from './api'
Vue.prototype.$api = api;
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
Vue.config.productionTip = false
require('./mock/mock.js');
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
更多推荐
已为社区贡献7条内容
所有评论(0)