vue3中使用ant-design-vue的layout組件實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)航欄和面包屑功能
0 前言
最近在自己搞一個(gè)前后端小項(xiàng)目,前端想使用ant-design-vue的layout組件實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)航欄和面包屑,但是網(wǎng)上的資料較少,所以我就自己整合實(shí)現(xiàn)了一下,在此記錄分享。
1 準(zhǔn)備工作
基于一個(gè)新建的Vue3項(xiàng)目上實(shí)現(xiàn)。
1.1 安裝ant-design-vue
官方文檔:Components Overview - Ant Design Vue (antdv.com)
安裝:
npm i --save ant-design-vue
全局注冊(cè):
import { createApp } from 'vue';
import Antd from 'ant-design-vue';
import App from './App';
import 'ant-design-vue/dist/antd.css';
const app = createApp(App);
app.use(Antd).mount('#app');1.2 安裝圖標(biāo)組件包
npm install --save @ant-design/icons-vue
main.js中引用并全局注冊(cè)
import * as Icons from '@ant-design/icons-vue'
//全局注冊(cè)圖標(biāo)
const icons = Icons
for (const i in icons) {
app.component(i, icons[i])
}2 選擇組件
如下圖所示,復(fù)制組件代碼:

3 路由文件
router/index.js文件
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
//導(dǎo)航頁
path: '/layout',
name: 'layout',
meta: {
title: '首頁',
keepalive: true
},
component: () => import('@/views/layout/'),
children: [
{
//歡迎頁
path: '/layout',
name: 'welcome',
meta: {
title: '首頁',
keepalive: true
},
component: () => import('@/views/welcome/')
},
{
//實(shí)時(shí)數(shù)據(jù)
path: '/runtimeData',
name: 'runtimeData',
meta: {
title: '實(shí)時(shí)數(shù)據(jù)',
keepalive: true
},
component: () => import('@/views/runtimeData/')
},
{
//數(shù)據(jù)分析
path: '/dataAnalysis',
name: 'dataAnalysis',
meta: {
title: '數(shù)據(jù)分析',
keepalive: true
},
component: () => import('@/views/dataAnalysis/')
},
{
//數(shù)據(jù)處理(增刪改查)
path: '/dataManage',
name: 'dataManage',
meta: {
title: '數(shù)據(jù)總覽',
keepalive: true
},
component: () => import('@/views/dataManage/')
},
{
//查看用戶信息
path: '/showUserInfo',
name: 'showUserInfo',
meta: {
title: '查看用戶信息',
keepalive: true
},
component: () => import('@/views/my/showUserInfo.vue')
},
{
//修改用戶信息
path: '/editUserInfo',
name: 'editUserInfo',
meta: {
title: '修改用戶信息',
keepalive: true
},
component: () => import('@/views/my/editUserInfo.vue')
},
]
},
{
//登錄頁面
path: '/login',
name: 'login',
meta: {
title: '登錄',
keepalive: true
},
component: () => import('@/views/login/index.vue')
},
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router4 Vue導(dǎo)航頁面
views/layout/index.vue,主要關(guān)注標(biāo)簽a-layout中的內(nèi)容及相關(guān)變量
<template>
<a-layout id="components-layout-demo-custom-trigger" style="min-height: 100vh">
<a-layout-sider v-model:collapsed="collapsed" collapsible>
<div class="logo">
溫濕度數(shù)據(jù)顯示
</div>
<a-menu @click="navClick"
v-model="currentSelectChild"
@openChange="onOpenChange"
:openKeys="currentParent"
:inline-collapsed="collapsed"
:selectedKeys="[route.path]"
theme="dark"
mode="inline"
>
<template v-for='(item,index) in NavDataInfo.NavData'>
<a-sub-menu :key="item.Path" v-if='item.Child.length > 0'>
<template #title>
<a-icon>
<meh-outlined/>
</a-icon>
<span>{{item.Title}}</span>
</template>
<a-menu-item v-for="(itChild,ind) in item.Child" :key="itChild.Path">
<a-icon>
<meh-outlined/>
</a-icon>
<router-link :to="itChild.Path">
<!--根據(jù)路徑去跳轉(zhuǎn)頁面-->
{{itChild.Title}}
</router-link>
</a-menu-item>
</a-sub-menu>
<a-menu-item :key="item.Path" v-else>
<a-icon>
<meh-outlined/>
</a-icon>
<router-link :to="item.Path">
<a-icon :type="item.Icons"/>
<span>{{item.Title}}</span>
</router-link>
</a-menu-item>
</template>
</a-menu>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0">
<div id="header">
<div id="left">
<span>作者:</span>
</div>
<div id="right">
<a-avatar src="https://joeschmoe.io/api/v1/random"/>
<el-dropdown>
<span class="el-dropdown-link">
User
<el-icon class="el-icon--right">
<arrow-down />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item><router-link to="/showUserInfo">我的信息</router-link></el-dropdown-item>
<el-dropdown-item><router-link to="/editUserInfo">修改信息</router-link></el-dropdown-item>
<el-dropdown-item><span @click="outLogin">退出登錄</span></el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
</a-layout-header>
<!-- <keep-alive>-->
<a-layout-content style="margin: 0 16px">
<!-- 面包屑 -->
<a-breadcrumb style="margin: 16px 0" separator=">">
<!-- 自定義返回函數(shù) ←-->
<a-breadcrumb-item @click="goback">
<a-icon>
<import-outlined/>
</a-icon>
返回
</a-breadcrumb-item>
<a-breadcrumb-item v-for="(item, index) in breadList" :key="item.name">
<router-link v-if="item.name !== name && index !== 1"
:to="{ path: item.path === '' ? '/' : item.path }">
{{ item.meta.title }}
</router-link>
<span v-else>
{{ item.meta.title }}
</span>
</a-breadcrumb-item>
</a-breadcrumb>
<!-- <transition>-->
<div :style="{ padding: '24px', background: '#fff', minHeight: '100%' }">
<router-view/>
</div>
<!-- </transition>-->
</a-layout-content>
<!-- </keep-alive>-->
<a-layout-footer style="text-align: center">
Great Project ?2022 Created by
</a-layout-footer>
</a-layout>
</a-layout>
</template>
<script setup>
import { ref, reactive, onBeforeMount, watch, createVNode } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Modal, message } from 'ant-design-vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import myRouter from '@/router'
import { ArrowDown } from '@element-plus/icons-vue'
//************************************************data部分
const route = useRoute()
const router = useRouter()
const collapsed = ref(false)
const selectedKeys = ref(['0'])
const name = ref('')
const breadList = ref([])
const NavDataInfo = reactive({
NavData: [
{
NavID: '0',
Icons: 'home',
Title: '首頁',
Path: '/layout',
Child: []
},
{
NavID: '1',
Icons: 'meh',
Title: '實(shí)時(shí)數(shù)據(jù)',
Path: '/runtimeData',
Child: []
},
{
NavID: '2',
Icons: 'like',
Title: '數(shù)據(jù)管理',
Path: '/dataManage',
Child: [
{
NavID: '2-1',
Icons: 'man',
Title: '數(shù)據(jù)總覽',
Path: '/dataManage',
Child: []
},
]
},
{
NavID: '3',
Icons: 'key',
Title: '數(shù)據(jù)分析',
Path: '/dataAnalysis',
Child: []
},
],
})
//************************************************data部分
//************************************************方法
const getBreadcrumb = () => {
breadList.value = []
name.value = route.name
route.matched.forEach(item => {
breadList.value.push(item)
})
console.log(breadList.value)
console.log(name.value)
console.log(route)
}
// 返回上一頁,調(diào)用的組件 router.back();
const goback = () => {
//點(diǎn)擊了返回按鈕
router.back()
}
//退出登錄
const outLogin = () => {
Modal.confirm({
title: '您確定要退出登錄嗎?',
icon: createVNode(ExclamationCircleOutlined),
content: createVNode('div', {
style: 'color:red;',
}, '點(diǎn)擊OK則將退出!'),
onOk () {
// console.log('OK', key)
message.success('退出登錄!')
myRouter.push({ path: "/login" });
},
onCancel () {
// console.log('Cancel')
message.success('取消成功!')
},
class: 'test',
})
}
//監(jiān)視路由
watch(() => route.path, getBreadcrumb)
//*************************************************方法
//*************************************************生命周期
onBeforeMount(() => {
getBreadcrumb()
})
//*************************************************生命周期
</script>
<style scoped>
#components-layout-demo-custom-trigger {
height: 100%;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color 0.3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #1890ff;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
background: rgb(127, 252, 255);
margin: 16px;
font-size: 20px;
text-align: center;
font-family: 宋體;
}
#header {
display: flex;
height: 70px;
/*margin: 0;*/
padding: 0;
}
#left {
width: 80%;
/*height: 25px;*/
/*background-color: darksalmon;*/
justify-content: flex-start;
display: flex;
align-items: center;
margin-left: 16px;
}
#right {
flex: 1;
width: 20%;
/*background-color: coral;*/
/*height: 50px;*/
justify-content: flex-end;
display: flex;
align-items: center;
margin-right: 16px;
}
.example-showcase .el-dropdown-link {
cursor: pointer;
color: var(--el-color-primary);
display: flex;
align-items: center;
}
</style>
上面的代碼中將路由文件中的路由表重新寫了一個(gè)變量,主要是為了方便,并不是所有頁面路由都要制作導(dǎo)航欄,這樣就不用在router/index.js中添加路由時(shí)考慮太多。
5 最終效果

效果如上圖所示,我這里也寫了一個(gè)面包屑,不過還有些問題,就交給大伙兒實(shí)現(xiàn)吧!
到此這篇關(guān)于vue3中使用ant-design-vue的layout組件實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)航欄和面包屑功能的文章就介紹到這了,更多相關(guān)vue3使用ant-design-vue實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)航欄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vant-ui框架的一個(gè)bug(解決切換后onload不觸發(fā))
這篇文章主要介紹了vant-ui框架的一個(gè)bug(解決切換后onload不觸發(fā)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-11-11
vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作
這篇文章主要介紹了vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
vue左側(cè)菜單,樹形圖遞歸實(shí)現(xiàn)代碼
這篇文章主要介紹了vue左側(cè)菜單,樹形圖遞歸實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
Electron-vue開發(fā)的客戶端支付收款工具的實(shí)現(xiàn)
這篇文章主要介紹了Electron-vue開發(fā)的客戶端支付收款工具的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
vue3?setup語法糖各種語法新特性的使用方法(vue3+vite+pinia)
這篇文章主要介紹了vue3?setup語法糖各種語法新特性的使用(vue3+vite+pinia),本文主要是記錄vue3的setup語法糖的各種新語法的使用方法,需要的朋友可以參考下2022-09-09
Vue項(xiàng)目打包成Docker鏡像包的簡(jiǎn)單步驟
最近做時(shí)速云項(xiàng)目部署,需要將前端項(xiàng)目打成鏡像文件,下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目打包成Docker鏡像包的簡(jiǎn)單步驟,需要的朋友可以參考下2023-10-10
vue3 + ts + pnpm:nprogress / 頁
NProgress是一款輕量級(jí)的進(jìn)度條庫,主要用于網(wǎng)頁頂部顯示頁面加載或運(yùn)行進(jìn)度,它易于安裝和使用,并提供良好的視覺效果,NProgress也可以與VueRouter結(jié)合使用,通過導(dǎo)航守衛(wèi)在路由跳轉(zhuǎn)時(shí)自動(dòng)顯示和隱藏進(jìn)度條,該庫的使用提高了用戶對(duì)網(wǎng)頁加載狀態(tài)的感知,優(yōu)化了用戶體驗(yàn)2024-09-09

