Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩+路由跳转router-view渲染数据 路由跳转到同一个页面带参数ID 自动刷新数据
丢你个滑稽 人气:0准备:导入ElementUI 看官网教程
数据准备:JSON数据转换成树状
参考文章: JS实现 JSON扁平数据转换树状数据
后台我拿的数据是这样的格式:
[ {id:1 , parentId: 0, name: '', level: 0}, {id:2 , parentId: 0, name: '', level: 0}, {id:3 , parentId: 2, name: '', level: 1}, {id:4 , parentId: 2, name: '', level: 1}, {id:5 , parentId: 4, name: '', level: 2}, ]
转换后的数据差不多就是这样的格式
{ [ { id: 1, name: '' }, { id: 2, name: '', children: [ { id: 3 }, { id: 4, children: [ { id: 5 } ] } ] }, ] }
自定义组件 路径 componebts/NavMenu.vue
<template> <fragment class="navMenu"> <template v-for="navMenu in navMenus"> <!-- 最后一级菜单 --> <el-menu-item v-if="!navMenu.children" :key="navMenu.menuId" :data="navMenu" :index="navMenu.menuUrl+'/'+navMenu.menuId">//带参数ID <i :class="navMenu.menuIcon"></i> <span slot="title" >{{navMenu.menuName}}</span> </el-menu-item> <!-- 此菜单下还有子菜单 --> <el-submenu v-if="navMenu.children" :key="navMenu.menuId" :data="navMenu" :index="navMenu.menuId">//navMenu.menuId解决跳转相同路由页面 展开菜单问题 <template slot="title"> <i :class="navMenu.menuIcon"></i> <span slot="title"> {{navMenu.menuName}}</span> </template> <!-- 递归 --> <NavMenu :navMenus="navMenu.children"></NavMenu> </el-submenu> </template> </fragment> </template> <script> export default { name: 'NavMenu', props: ['navMenus'], data() { return {} }, methods: {} } </script> <style> </style>
自定义组件包含在 fragment 不是div 不然展开和缩人会出现显示问题
如下:
解决菜单导航折叠后文字不隐藏
出现这个问题是因为我们在<el-menu>嵌套中出现了意料之外的<div>,而<el-menu>标签本身希望里面嵌套的是<el-menu-item>,<el-submenu>,<el-menu-item-group>其中之一
但是我们又不能直接删掉<div>,因为<template>中包含的必须是一个根标签,而v-for会形成不确定的并列标签
项目安装vue-fragment
cnpm install --save vue-fragment
在main.js中引入
// main.js
import Fragment from 'vue-fragment'
Vue.use(Fragment.Plugin)
<div>修改为<fragment>即可
:index="" 指的是路由跳转的地址
路径 在你需要的页面引入组件 嵌套在div里面可以避免不必要的错误
<template> <div > <el-menu default-active="this.$router.path" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" :collapse="isCollapse" mode="vertical" background-color="#2c2e2f" text-color="#bfcbd9" active-text-color="#85c1e7" :default-active="activeIndex" router> <NavMenu :navMenus="sret"></NavMenu> </el-menu>
<router-view :key="$route.path + $route.query.t"></router-view>
:key="$route.path + $route.query.t" //解决跳转到相同路由页面 数据不刷新问题
</div> </template>
<script type="text/ecmascript-6"> import NavMenu from "@/components/NavMenu" //组件位置 export default { components: { //定义组件 NavMenu, }, name: 'login', data() { return {} } }
:navMenus="sret" 这里的sret是后台拿过来的JSON树状数据 数据要转换成树状的 不然不行 吧转换后的数据赋值sret
让路由在<router-view></router-view>打开
定义路由和跳转的页面
路径 router/index.js 里面
需要几个页面就按这样的跳转 都要引入
import Ibookmark from '@/views/bookmark';
..........
// 启用路由
Vue.use(Router);
// 导出路由
export default new Router({
routes: [{
path: '/login',
name: '',
component: login,
children: [
{
path: '/bookmark/:menuId',
component: resolve => require(['../views/bookmark.vue'], resolve),
query:{
t:Date.now(), //解决跳转到相同路由页面 数据不刷新问题
},
},
],
},........省略
父子路由 是层级关系 children: []
:index="navMenu.menuUrl+'/'+navMenu.menuId"
注意看 路径 我这里传了ID参数 是为了在路由里面显示不同的数据
然后在路由的页面 获取点击的菜单id 渲染不同的数据
this.$route.params this.$route.query 多种取值的方式我都试了 没成功在页面取出id
然后我用的是URL的截取/后面的ID方法
aaa() {
var _this=this
var url = window.location.href;
var index = url.lastIndexOf("\/");
_this.menuId = url.substring(index + 1,url.length);
},
获取到最后一个斜杠后面的数据 赋值给menuId
实现 菜单跳转到相同的路由 根据ID渲染不同的数据 如果不设置:key="$route.path + $route.query.t" 会出现数据ID不刷新问题
设置后 每次跳转 都会出现读取id 然后操作ID操作数据
加载全部内容