1. 基本使用
1. 安装vue-router
pnpm install vue-router --save
2. 配置router/index.js
文件
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
3. 配置main.js
文件
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App);
app.use(router)
app.mount('#app')
4. 配置App.vue
文件
<template>
<div id="app">
<router-view />
</div>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
5. 配置home.vue
文件
<template>
<div>
<h1>Home</h1>
</div>
</template>
<script setup>
</script>
2. 使用发布订阅模式配置拦截器
1. 编写发布订阅模式
class PubSub {
listeners = {};
constructor() {
this.listeners = {};
}
on(eventName = '', listener) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = [];
}
listener && this.listeners[eventName].push(listener);
}
off(eventName = '', listener) {
if (!listener || !this.listeners[eventName]) {
console.log('not on event ', eventName, 'or listener must be a function');
return;
}
this.listeners[eventName].some((item, idx) => {
if (item.name === listener.name) {
this.listeners[eventName].splice(idx, 1);
return true;
}
return false;
});
}
emit(eventName = '', ...args) {
if (!this.listeners[eventName]) {
console.log('not on event ', eventName);
return [];
}
const results = [];
this.listeners[eventName].forEach((listener) => {
const res = listener.apply(this, args);
if (res !== undefined) {
results.push(res);
}
});
return results;
}
}
const pubsub = new PubSub();
export default pubsub;
export const ROUTER_BEFOREEACH = 'router:beforeEach';
export const ROUTER_AFTEREACH = 'router:afterEach';
export const ROUTER_ERROR = 'router:error';
2. 新增router/intercept.js
文件,在对应的地方发布订阅事件
import pubsub, { ROUTER_BEFOREEACH, ROUTER_AFTEREACH, ROUTER_ERROR } from '@/utils/pubsub';
const intercept = (router) => {
pubsub.on(ROUTER_BEFOREEACH, (to, from) => {
console.log('beforeEach', to, from);
return true;
});
pubsub.on(ROUTER_AFTEREACH, (to, from) => {
console.log('afterEach', to, from);
})
pubsub.on(ROUTER_ERROR, (error) => {
console.log('error', error);
})
router.beforeEach((to, from, next) => {
const result = pubsub.emit(ROUTER_BEFOREEACH, to, from);
if (!result || result.some((item) => item === false)) {
next(false);
} else {
next();
}
});
router.afterEach((to, from) => {
pubsub.emit(ROUTER_AFTEREACH, to, from);
})
router.onError((error) => {
pubsub.emit(ROUTER_ERROR, error);
})
}
export default intercept;
3. 配置router/index.js
文件
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/views/Home.vue'
import intercept from '@/router/intercept'
const routes = [
{
path: '/',
name: 'Home',
component: Home
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
intercept(router)
3. 读取文件目录生成路由
1. 新增router/generate.js
文件
import routeConfig from './config';
const generate = () => {
const routes = [];
const modules = import.meta.glob("@/views/**/*.vue");
for (const [pathKey, moduleImport] of Object.entries(modules)) {
if (pathKey.includes('components') || pathKey.includes('layouts')) {
continue;
}
const matchResult = pathKey.match(/\/views\/(.*?)\.vue$/);
if (!matchResult) {
continue;
}
const pageName = matchResult[1];
let idArr = pageName.split('/'), id = idArr[idArr.length - 1];
const { name = id, meta = {} } = routeConfig[pageName] || {};
routes.push({
path: '/' + pageName,
name,
id,
component: () => moduleImport().then(m => m.default),
meta
});
}
return routes;
}
export default generate;
4. 配置对应的路由信息,如 meta
export default {
'home': {
name: '首页',
meta: {
title: '首页'
}
}
}
5. 最后完整的router/index.js
文件
import { createRouter, createWebHashHistory } from 'vue-router';
import intercept from './intercept';
import generate from './generate';
const routes = [
{
path: '/',
redirect: '/home'
},
...generate()
];
console.log(routes);
const router = createRouter({
history: createWebHashHistory(),
routes
})
intercept(router);
export default router