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)航頁(yè) path: '/layout', name: 'layout', meta: { title: '首頁(yè)', keepalive: true }, component: () => import('@/views/layout/'), children: [ { //歡迎頁(yè) path: '/layout', name: 'welcome', meta: { title: '首頁(yè)', 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') }, ] }, { //登錄頁(yè)面 path: '/login', name: 'login', meta: { title: '登錄', keepalive: true }, component: () => import('@/views/login/index.vue') }, ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router
4 Vue導(dǎo)航頁(yè)面
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)頁(yè)面--> {{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: '首頁(yè)', 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) } // 返回上一頁(yè),調(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>
上面的代碼中將路由文件中的路由表重新寫(xiě)了一個(gè)變量,主要是為了方便,并不是所有頁(yè)面路由都要制作導(dǎo)航欄,這樣就不用在router/index.js中添加路由時(shí)考慮太多。
5 最終效果
效果如上圖所示,我這里也寫(xiě)了一個(gè)面包屑,不過(guò)還有些問(wèn)題,就交給大伙兒實(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)文章
Vue3中如何使用rem來(lái)控制字體大小問(wèn)題
這篇文章主要介紹了Vue3中如何使用rem來(lái)控制字體大小問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07vant-ui框架的一個(gè)bug(解決切換后onload不觸發(fā))
這篇文章主要介紹了vant-ui框架的一個(gè)bug(解決切換后onload不觸發(fā)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作
這篇文章主要介紹了vue項(xiàng)目中微信登錄的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09vue左側(cè)菜單,樹(shù)形圖遞歸實(shí)現(xiàn)代碼
這篇文章主要介紹了vue左側(cè)菜單,樹(shù)形圖遞歸實(shí)現(xiàn)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08Electron-vue開(kāi)發(fā)的客戶端支付收款工具的實(shí)現(xiàn)
這篇文章主要介紹了Electron-vue開(kāi)發(fā)的客戶端支付收款工具的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05Vue 監(jiān)聽(tīng)元素前后變化值實(shí)例
這篇文章主要介紹了Vue 監(jiān)聽(tīng)元素前后變化值實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07vue3?setup語(yǔ)法糖各種語(yǔ)法新特性的使用方法(vue3+vite+pinia)
這篇文章主要介紹了vue3?setup語(yǔ)法糖各種語(yǔ)法新特性的使用(vue3+vite+pinia),本文主要是記錄vue3的setup語(yǔ)法糖的各種新語(yǔ)法的使用方法,需要的朋友可以參考下2022-09-09Vue項(xiàng)目打包成Docker鏡像包的簡(jiǎn)單步驟
最近做時(shí)速云項(xiàng)目部署,需要將前端項(xiàng)目打成鏡像文件,下面這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目打包成Docker鏡像包的簡(jiǎn)單步驟,需要的朋友可以參考下2023-10-10vue3 + ts + pnpm:nprogress / 頁(yè)
NProgress是一款輕量級(jí)的進(jìn)度條庫(kù),主要用于網(wǎng)頁(yè)頂部顯示頁(yè)面加載或運(yùn)行進(jìn)度,它易于安裝和使用,并提供良好的視覺(jué)效果,NProgress也可以與VueRouter結(jié)合使用,通過(guò)導(dǎo)航守衛(wèi)在路由跳轉(zhuǎn)時(shí)自動(dòng)顯示和隱藏進(jìn)度條,該庫(kù)的使用提高了用戶對(duì)網(wǎng)頁(yè)加載狀態(tài)的感知,優(yōu)化了用戶體驗(yàn)2024-09-09