先简单的记录,之后有时间再详细描述
简单使用
- 安装
pnpm install vue-router@4
- 创建router文件夹,并包括以下几个文件
- index.ts 文件是用于将modules文件夹的文件路由结构,并加载至routes里面
import { createWebHistory, RouteRecordRaw } from 'vue-router';
import { createRouter } from 'vue-router';
// 使用vite中的globEager方法读取目录下的所有ts文件
const routes: RouteRecordRaw[] = [];
const modules = import.meta.globEager('./modules/*.ts');
for (const path in modules) {
routes.push(...modules[path].default);
}
const router = createRouter({
history: createWebHistory(),
routes: routes,
});
export default router;
- 以home.ts为例
import { RouteRecordRaw } from 'vue-router';
// ts 中的验证
const routes: RouteRecordRaw[] = [
{
path: '/',
redirect: { name: 'GIS' }, // 首页默认跳转路径
component: () => import('@/pages/home/index.vue'),
children: [
{
path: 'gis',
name: 'GIS',
component: () => import('@/pages/home/gis/GIS.vue'),
},
{
path: 'test1',
name: 'test1',
component: () => import('@/pages/home/other/test1.vue'),
},
{
path: 'test2',
name: 'test2',
component: () => import('@/pages/home/other/test2.vue'),
},
],
},
{
path: '/gis',
component: () => import('@/pages/home/gis.vue'),
},
];
export default routes;
至此已经可以完成了基本功能的使用。
高级应用
为了规范化typescript开发,增加路由对象类型限制,好处:允许在基础路由里面增加开发者自定义属性,但是有时需要扩展一些字段来定制应用。
- 新增RouteRecordRaw的类型校验
// 注意:在给路由对象新增类型后,在每个路由对象里新增hidden或者其他属性会报错,
// 解决办法:在src目录下新增一个路由声明文件,扩展基础路由对象属性。
vue-router.d.ts,内容如下:
```typescript
import { _RouteRecordBase } from 'vue-router';
// 同名接口会自动合并
declare module 'vue-router'{
interface _RouteRecordBase{
hidden?: boolean | string | number
}
}
- 还可以将字段放置在meta元数据里面,推荐这种
import { RouteRecordRaw } from 'vue-router';
// ts 中的验证
const routes: RouteRecordRaw[] = [
{
path: '/login',
component: () => import('@/pages/login/index.vue'),
meta: {
title: '登录',
},
},
];
export default routes;
设置登录用户才能访问、404页面
// 写在main.ts文件中,因为pinia的原因,写在此处才可
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { createPinia, storeToRefs } from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persist';
// import './index.scss';
import './assets/style/app.scss';
import '@purge-icons/generated'; // 添加进来
import VueCesium from 'vue-cesium';
import 'vue-cesium/dist/index.css';
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
if (typeof (window as any).global === 'undefined') {
(window as any).global = window;
}
const pinia = createPinia();
pinia.use(piniaPluginPersist);
const app = createApp(App);
app.use(router);
app.use(pinia);
app.use(ElementPlus);
app.use(VueCesium, {
// cesiumPath 是指引用的Cesium.js路径,如
cesiumPath: './Cesium/Cesium.js',
// cesiumPath: 'https://unpkg.com/cesium/Build/Cesium/Cesium.js'
// cesiumPath: 'https://www.supermapol.com/earth/Build/Cesium/Cesium.js',
// 使用Cesium ion的数据源需要到https://cesium.com/ion/申请一个账户,获取Access Token。不指定的话可能导致 CesiumIon 的在线影像、地形加载失败
// accessToken: 'Your Cesium Ion defaultAccessToken'
});
app.mount('#app');
import userUserStore from '@/store/modules/useUserStore';
import { ElNotification, ElMessage } from 'element-plus';
const idUser = storeToRefs(userUserStore()).id;
router.beforeEach((to, from, next) => {
// 设置浏览器标题
if (to.meta.title) {
document.title = String(to.meta.title);
} else {
document.title = '滑坡监测平台';
}
// 路由出错处理
if (to.matched.length === 0 && !to.name) {
ElNotification({
title: 'Error',
message: 'This is an error message',
type: 'error',
duration: 5000,
});
ElMessage.error('404');
router.push('/404');
} else if (to.path !== '/login' && to.path !== '/404') {
if (idUser.value === -1) {
console.log('未登录');
ElNotification({
title: '未登录状态',
message: '您当前未登录,请登录后再访问!',
type: 'error',
duration: 5000,
});
ElMessage.error('您当前未登录,请登录后再访问!');
router.push('/login');
}
}
next();
});