Vue+elementUI 自定義動態資料選單導航元件實現展開收縮+路由跳轉router-view渲染資料 路由跳轉到同一個頁面帶引數ID 自動重新整理資料
阿新 • • 發佈:2020-02-01
準備:匯入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操作資料
&n