安裝
pnpm add vue-router@4
一、創(chuàng)建路由配置
1.1、創(chuàng)建 src/router/routes/index.ts 文件,并進行路由配置
// src/router/routes/index.ts
import type { RouteRecordRaw } from 'vue-router'
import { DashboardOutlined, HomeOutlined } from '@ant-design/icons-vue'
import { LOGIN_NAME, PAGE_NOT_FOUND_NAME } from '../constant'
export const routesList: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Layout',
redirect: '/dashboard/welcome',
component: () => import('@/layout/layout.vue'), // 需要創(chuàng)建 src/layout/layout.vue 文件否則會報錯
meta: {
title: '首頁',
fullPath: '/',
},
children: [
{
path: '/dashboard',
name: 'Dashboard',
redirect: '/dashboard/welcome',
meta: {
title: '概覽頁',
fullPath: '/dashboard',
icon: DashboardOutlined,
},
children: [
{
path: 'welcome',
name: 'DashboardWelcome',
meta: {
title: '工作臺',
fullPath: '/dashboard/welcome',
icon: HomeOutlined,
},
component: () => import('@/views/dashboard/welcome/welcome.vue'), // 需要創(chuàng)建 src/views/dashboard/welcome/welcome.vue 文件否則會報錯
},
],
},
{
path: '/account',
redirect: '/account/settings',
name: 'Account',
meta: {
title: '個人中心',
fullPath: '/account',
hideInMenu: true,
},
children: [
{
path: 'settings',
name: 'AccountSettings',
component: () => import('@/views/account/settings/settings.vue'),
meta: {
title: '個人設(shè)置',
fullPath: '/account/settings',
},
},
],
},
],
},
{
path: '/login',
name: LOGIN_NAME,
component: () => import('@/views/login/login.vue'),
meta: {
title: '登錄',
},
},
{
path: '/:pathMatch(.*)*', // 捕獲所有路由或 404 Not found 路由
name: PAGE_NOT_FOUND_NAME,
meta: {
title: '404 Not found',
},
component: () => import('@/views/error/404.vue'), // 需要創(chuàng)建 src/views/error/404.vue 文件否則會報錯
}
];
1.2、創(chuàng)建 types/vue-router.d.ts 自定義路由配置項 meta: RouteMeta 的類型聲明
// types/vue-router.d.ts
import type { RouteMeta as VRouteMeta } from 'vue-router'
declare module 'vue-router' {
interface RouteMeta extends VRouteMeta {
/** 標題 */
title: string;
/** 當前路由所在的完整路徑, 用來實現(xiàn)登錄后的重定向功能 */
fullPath: string
/**
* 菜單圖標; antd 圖標名稱, 這是臨時寫法
* TODO: 后期還要根據(jù) antd icon 中提供的方法,進行自定義一些圖標,但是需要注意的是,自定義圖標后需要驗證側(cè)邊欄菜單中的圖標是否還能正常展示
* 例如: antd 圖標為 <StepBackwardOutlined />,那么 icon 屬性的值則是:StepBackwardOutlined
*/
icon?: any;
/** 是否需要緩存 */
keepAlive?: boolean
/** 是否外鏈 */
isExt?: boolean
/**
* 外鏈打開方式
* 1: 新窗口打開
* 2: 內(nèi)嵌 iframe
*/
extOpenMode?: 1 | 2
/** 是否隱藏頁面加載進度條 */
hideProgressBar?: boolean;
/**
* 不在菜單中顯示
* 此屬性只會控制側(cè)邊欄中的一級菜單是否展示,不會對子級菜單的是否展示進行控制
* 如果要對子級菜單進行控制,請使用 hideChildrenInMenu 屬性
*/
hideInMenu?: boolean
/**
* 在菜單中隱藏子節(jié)點, 一般在 children 中有隱藏的子節(jié)點時,可以設(shè)置 hideChildrenInMenu: true 來只顯示父級菜單名稱
* 例如: 父級菜單: 用戶列表頁 (/user/list) 路由配置中可以設(shè)置 hideChildrenInMenu: true,
* 例如: 子級菜單: 用戶詳情頁 (/user/list/1, /user/list/2, /user/list/3) 不會出現(xiàn)在菜單中
*/
hideChildrenInMenu?: boolean
/** 不在頁面 header 中的面包屑導航中顯示 */
hideInBreadcrumb?: boolean
/** 不在tab標簽頁中顯示 */
hideInTabs?: boolean
}
}
1.3、創(chuàng)建 src/layout/layout.vue 文件
// src/layout/layout.vue
<script setup>
</script>
<template>
<div class="mt-12px">layout/layout.vue</div>
<router-view />
</template>
<style scoped>
</style>
1.4、創(chuàng)建 src/views/dashboard/welcome/welcome.vue 文件
// src/views/dashboard/welcome/welcome.vue
<script setup>
</script>
<template>
<div class="mt-12px">
工作臺
</div>
</template>
<style scoped>
</style>
1.5、創(chuàng)建 src/views/login/login.vue 文件
// src/views/login/login.vue
<script setup lang="ts">
import { message } from 'ant-design-vue'
import { ref } from 'vue'
const loading = ref(false)
const loginFormModel = ref({
username: 'admin',
password: 'a123456',
})
const handleSubmit = async () => {
const { username, password } = loginFormModel.value
if (username.trim() === '' || password.trim() === '') {
return message.warning('用戶名或密碼不能為空!')
}
message.loading('登錄中...', 0)
loading.value = true
}
</script>
<template>
<div class="login-box">
<div class="login-logo">
<img src="~@/assets/logo.svg" width="45">
<h1 class="mb-0 ml-2 text-3xl font-bold">
后臺管理系統(tǒng)
</h1>
</div>
<a-form layout="horizontal" :model="loginFormModel" @submit.prevent="handleSubmit">
<a-form-item>
<a-input v-model:value="loginFormModel.username" size="large" placeholder="admin">
<template #prefix>
<Icon icon="ant-design:user-outlined" />
</template>
</a-input>
</a-form-item>
<a-form-item>
<a-input
v-model:value="loginFormModel.password"
size="large"
type="password"
placeholder="a123456"
autocomplete="new-password"
>
<template #prefix>
<Icon icon="ant-design:lock-outlined" />
</template>
</a-input>
</a-form-item>
<a-form-item>
<a-button type="primary" html-type="submit" size="large" :loading="loading" block>
登錄
</a-button>
</a-form-item>
</a-form>
</div>
</template>
<style lang="less" scoped>
.login-box {
display: flex;
flex-direction: column;
align-items: center;
width: 100vw;
height: 100vh;
padding-top: 240px;
background: #fff;
background-size: 100%;
.login-logo {
display: flex;
align-items: center;
margin-bottom: 30px;
}
:deep(.ant-form) {
width: 400px;
.ant-col {
width: 100%;
}
.ant-form-item-label {
padding-right: 6px;
}
}
}
</style>
1.6、創(chuàng)建 src/views/error/404.vue 文件
// src/views/error/404.vue
<script setup>
</script>
<template>
<div class="mt-12px">src/views/error/404.vue</div>
</template>
<style scoped>
</style>
二、創(chuàng)建路由實例
2.1、創(chuàng)建 src/router/index.ts 文件,并進行實例化路由器
// src/router/index.ts
import type { App } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import { routesList } from './routes'
export const router = createRouter({
// import.meta.env.BASE_URL
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: routesList, // 將 1.1 中創(chuàng)建好的路由配置引入到這里
});
// 通過 setupRouter 函數(shù)將 router 實例傳遞給 app 應(yīng)用
export async function setupRouter(app: App) {
app.use(router)
// 路由準備就緒后,路由插件幫我們做了如下操作:
// 1、全局注冊 RouterView 和 RouterLink 組件。
// 2、添加全局 $router 和 $route 屬性(可以在組件模板中使用)
// 3、啟用 useRouter() 和 useRoute() 組合式函數(shù)。
// 4、觸發(fā)路由器解析初始路由。
await router.isReady()
}
export default router;
三、注冊路由器插件(在 src/main.ts 中)
// src/main.ts
import { createApp } from 'vue'
const app = createApp(App)
// 掛載路由
async function setupAppRouter() {
await setupRouter(app)
// 路由準備就緒后才能掛載APP實例
app.mount('#app')
}
setupAppRouter()
四、添加路由出口(在 src/App.vue 中)
// src/App.vue
<template>
<!-- 采用 RouterView 插槽的方式設(shè)置路由出口,便于擴展其它功能 -->
<router-view v-slot="{ Component }">
<component :is="Component" />
</router-view>
</template>