網站導航欄設計(vue3構建admin後臺管理系統)

系列文章目錄vue3構建view admin後臺管理系統(1)——技術選型vue3構建view admin後臺管理系統(2)——Vue Router使用詳解vue3構建view admin後臺管理系統(3)——基於Vue Router實現導航欄前言上篇文章我們講解瞭Vue Router路由管理工具基本的使用,但是如果同學們沒有項目經驗,即時看明白官方文檔,也很難真正將所學應用到項目中,造成一看就懂,一用就廢的尷尬局面。如何把Vue Router真正應用到項目中,才是我們的重中之重。其實寫這篇文章之前,我是很猶豫的,因為很多東西,原理很簡單,應用就略麻煩,寫出來就更麻煩,最主要的是,我也不知道寫完瞭,會不會有幫助。在這裡拋磚引玉,有不當的地方,歡迎大佬指正。編輯切換為居中在這裡插入圖片描述一、嵌套路由本篇文章有一個躲不過的基礎概念——Vue Router的嵌套路由。詳細概念請一定移步官網仔細閱讀,這裡隻是做個概述,幫助曾經閱讀過官網的同學喚起記憶。我們在路由定義文件router.js中定義過路由數據:const routes = [{ path: '/user/:id', component: User }]我們在頁面入口文件APP.vue中定義過路由入口:<router-view></router-view>當我們在main.js中引入router插件,就會自動把routes中定義的路由信息拿到,然後根據我們定義的事件,把對應的組件渲染到router-view中。這裡的意思就是把User組件渲染到router-view的位置。如果User組件中還存在router-view標簽,就是路由嵌套,則會在User中的router-view位置渲染routes中定義的對應的children內容。如:const routes = [
{
path: '/user/:id',
component: User,
children: [
{
// 當 /user/:id/profile 匹配成功
// UserProfile 將被渲染到 User 的 <router-view> 內部
path: 'profile',
component: UserProfile,
},
{
// 當 /user/:id/posts 匹配成功
// UserPosts 將被渲染到 User 的 <router-view> 內部
path: 'posts',
component: UserPosts,
},
],
},
]如果User組件的內容如下:const User = {
template: `
<div class="user">
<h2>User {{ $route.params.id }}</h2>
<router-view></router-view>
</div>
`,
}那麼就會在User組件中的router-view渲染UserProfile和UserPosts。以上就是路由嵌套的大體內容。User可以視為父組件,UserProfile和UserPosts則為子組件。二、使用步驟1.梳理文件關系如果對router插件的使用有疑惑的同學請翻閱我上篇文章,這裡假定你已經對router的基本使用都熟悉瞭。我們先梳理清楚路由涉及的幾個主要組件: 1. APP.vue (基本每個vue項目都有) 2. layout.vue (我自定義的佈局組件,有些框架裡也叫main.vue、home.vue之類的) 3. SideMenu.vue (我自定義的導航組件,包含在layout.vue中) 4. 各個業務的組件上節有提及App.vue中存在路由的入口<router-view></router-view>router.js中的數據都會渲染在這裡。router.js代碼精簡後,隻留下幾條數據:import Login from 'module-base/views/Login/Login.vue'
import Layout from 'module-base/views/Layout/Layout.vue'
export const routes = [
{
path: '/login',
name: 'login',
component: Login, //默認直接加載
meta: {
hideInMenu: true
}
},
{
path: '/home',
name: 'home',
component: Layout,
children: [
{
path: '/home_page',
name: 'home_page',
meta: {
title: '首頁',
icon: 'ios-list-box'

},
component: () => import('module-base/views/Home.vue')
}
]
},
{
path: '/mailSend',
name: 'mailSend',
component: Layout,
meta: {
showAlways: true,
title: '表單',
icon: 'ios-list-box',
// hideInMenu: true

},
children: [
{
path: '/mailSend_page',
name: 'mailSend_page',
meta: {
title: '表單示例',
icon: 'ios-list-box'

},
component: () => import('@/views/MailSend/MailSend.vue')
}
]
}
]router.js裡面有兩個組件Login、Layout是先加載,然後定義到component屬性,而其他組件都是通過以下代碼加載:() => import('@/views/MailSend/MailSend.vue')這是一種動態加載組件的方式,可以做到按需加載,優化速度。我們可以發現,除瞭“path: '/login'”部分,是直接加載login,後面的都定義瞭一個屬性:component: Layout這說明我們每個業務頁面,其實都是嵌套在Layout組件中,Layout就是我們所有頁面的父組件,其他業務頁面則是子組件,如children中定義的Home.vue、MailSend.vue。2.瞭解佈局組件Layout .vue我們把Layout.vue中的主要html代碼摘抄出來:<div class="layout">
<Layout style="height: 100%">
<Sider ref="side1" style="min-width: 100px" hide-trigger collapsible :collapsed-width="78" v-model="isCollapsed">
<SideMenu ref="sideMenu" :menu-list="menuList" @on-select="turnToPage_sideMenu"></SideMenu>
<svg class="icon icon-menu" @click="collapsedSider" aria-hidden="true">
<use xlink:href="#icon-pendant-full"></use>
</svg>
</Sider>

<Layout>
<Content :style="{overflowY:'auto',overflowX:'auto', background: '#fff', minHeight: '260px'}">
<!–router-view嵌套,這裡渲染Layout路由的children路由 –>
<router-view v-slot="{Component}">
<KeepAlive :max="10">
<component :is="Component"></component>
</KeepAlive>
</router-view>
</Content>
</Layout>
</Layout>
</div>這段代碼十分簡單,主要分為兩部分,一個是Sider,就是左側的導航欄,一個是Layout(iview框架提供的佈局標簽),就是右側渲染組件內容的區域,Layout標簽裡有router-view標簽,這裡和App.vue中的router-view就組成瞭路由嵌套。所以子組件Home.vue、MailSend.vue等都會渲染在這裡。Layout標簽部分沒什麼好說的,都是router插件的基礎應用。Sider標簽中的svg是應用的阿裡iconfont,看不明白可忽略。這部分的核心其實是SideMenu組件。3.瞭解導航組件SideMenuSideMenu組件相對於Layout.vue就相對復雜一些瞭,因為對於router.js中一些自定義信息的判斷,都是在這裡,代碼如下:<Menu theme="dark" width="auto" :class="menuitemClasses">
<template v-for="item in menuList">
<template v-if="item.children && item.children.length === 1">
<!– 隻有一個children元素的情況–>
<SideMenuItem v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></SideMenuItem>
<MenuItem v-else :name="getNameOrHref(item,true)" :key="`menu-${item.children[0].name}`">
<svg v-if="item.children[0].meta.iconfont" class="icon" aria-hidden="true">
<use xlink:href="#icon-weixin"></use>
</svg>
<Icon v-else :type="item.children[0].meta.icon"></Icon>
<span v-if="!isCollapsed" :class="{active:!isCollapsed}">{{ showTitle(item.children[0]) }}</span>
</MenuItem>
</template>
<template v-else>
<!– 沒有children或者有多個children的情況–>
<SideMenuItem v-if="showChildren(item)" :key="`menu-${item.name}`" :parent-item="item"></SideMenuItem>
<MenuItem v-else :name="getNameOrHref(item)" :key="`menu-${item.name}`">
<svg v-if="item.meta.iconfont" class="icon" aria-hidden="true">
<use xlink:href="#icon-weixin"></use>
</svg>
<Icon v-else :type="item.meta.icon"></Icon>
<span v-if="!isCollapsed" :class="{active:!isCollapsed}">{{ showTitle(item) }}</span>
</MenuItem>
</template>
</template>
</Menu>導航主要應用瞭iview框架的Menu組件。我們渲染導航,總得根據一個數組數據來渲染吧,這個數據從哪來的,沒錯,就是從router.js中獲取的。我的router數據傳輸過程大致為:1. 在pinia中定義獲取router.js數據的getters方法,pinia是類似vuex的全局管理工具。 2. 在Layout.vue中調用pinia,獲取router.js中的數據定義為:menuList3. 通過父子組件傳參,把menuList傳遞給sideMenu組件。4. sideMenu得到組件後,開始對它進行循環渲染,這就是上面的:v-for="item in menuList"在渲染過程中,可以通過item的一些自定義配置,來控制渲染效果,比如我的導航欄裡,有以下幾個處理: 1. 根據節點item是否存在children對象,判斷是否渲染二級導航欄。 2. 我自定義瞭一個meta屬性,裡面會有一些自定義參數,比如我會在sideMenu中判斷 icon來決定渲染的圖標,根據title來判斷渲染標題。4. 實現跳轉Layout和SideMenu組件都講解完畢,那是如何做到點擊導航欄實現跳轉的呢?答案是,我在Layout組件中寫入SideMenu時,定義瞭一個方法@on-select="turnToPage_sideMenu",當點擊選擇導航欄時,調用方法如下:function turnToPage_sideMenu(name) {
console.log(name)
turnToPage(router, name)
}

//在另一個工具函數中定義瞭方法turnToPage
export const turnToPage= ($router,route)=> {
let { name, params, query } = {}
if (typeof route === 'string') name = route
else {
name = route.name
params = route.params
query = route.query
}
if (name.indexOf('isTurnByHref_') > -1) {
window.open(name.split('_')[1])
return
}
$router.push({
name,
params,
query
})
}總結這部分代碼略多,沒辦法都粘貼上來,如果有興趣詳細瞭解的同學,可私聊或評論我獲取源碼。根據路由信息渲染導航欄其實思路很簡單:1. App.vue中定義router-view標簽,作為路由入口 2. 除瞭login等特殊組件,每個業務組件的父級component都定義一個Layout佈局組件,這樣每次跳轉到不同組件,都有父組件Layout3. Layout佈局組件中做兩件事:一是SideMenu導航組件,二是定義router-view作為嵌套的子路由,用來渲染router.js中children裡定義的組件。 4. 在全局管理工具中獲取router信息,如果不考慮後續,甚至可以不用全局管理工具,直接在需要的組件中獲取即可。把menulist渲染到SideMenu導航組件5. 定義跳轉方法turnToPage_sideMenu,點擊導航欄時跳轉到對應的組件。


本文出自快速备案,转载时请注明出处及相应链接。

本文永久链接: https://www.xiaosb.com/beian/52281/