Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩+路由跳转router-view渲染数据 路由跳转到同一个页面带参数ID 自动刷新数据

时间:2023-03-08 18:16:43
Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩+路由跳转router-view渲染数据 路由跳转到同一个页面带参数ID 自动刷新数据

准备:导入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>即可 Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩+路由跳转router-view渲染数据 路由跳转到同一个页面带参数ID 自动刷新数据
: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: []

Vue+elementUI 自定义动态数据菜单导航组件实现展开收缩+路由跳转router-view渲染数据 路由跳转到同一个页面带参数ID 自动刷新数据

: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操作数据