截止2024-2-1,网上找的插件有uni-simple-router和@gowiny/uni-router,前者vue2版本免费、vue3版本收费,后者是vue3但是打包报错 因为没找到合适的vue3用的路由插件,只能参照vue2的插件弄一个,只做了跳转的全局拦截,跟vue-router还是差很多的。
已知的问题有:
- 页面加载和跳转两种方式执行beforeEach和onload的顺序不同
- 监听或重写popstate和pushState等会报错,原因是编译到h5平台uniapp会自动引入vue-router,不允许进行popstate等的重写覆盖
- 小程序方面没试过,理论上也能用
最后,如果想要实现拦截,还是考虑付钱或者用回vue2。自己也是放弃这个用回vue2。
要是觉得有侵权请联系我
const isSameRoute = (a, b) => a === b && a !== "/" && b !== "/" && !!(a || b);
const navigateApis = ["navigateTo", "redirectTo", "reLaunch", "switchTab"];
let initPageApis = [];
// 此处是因为百度小程序在onLoad之前会有onInit,但是这里只需要处理第一个执行的周期
// #ifdef MP-BAIDU
initPageApis = ["onInit"];
// #endif
// #ifndef MP-BAIDU
initPageApis = ["onLoad"];
// #endif
// 不用onReady是因为onReady执行一次但不是所有情况都执行,所以选择每次都执行的onShow
const showApis = ["onShow"];
const pageApis = [...initPageApis, ...showApis];
const navigateApisProxy = router => {
navigateApis.forEach(key => {
uni.addInterceptor(key, {
invoke(config) {
const { beforeEach, setTo, setFrom, setLockKey } = router;
const pageArr = getCurrentPages();
const currPath = pageArr[pageArr.length - 1]?.$page.fullPath;
if (isSameRoute(config.url, currPath)) return false;
if (beforeEach(config.url, currPath)) {
setLockKey(key);
setTo(config.url);
setFrom(currPath);
return true;
}
return false;
},
success() {
const { afterEach, setFrom } = router;
afterEach(router.to, router.from);
setFrom(router.to);
}
});
});
};
const pageApisMixin = router => ({
// vue文件不要用这个生命周期
beforeCreate() {
// 只处理页面文件
if (this.$mpType !== "page") return;
pageApis.forEach(key => {
const originFun = this.$[key] || [];
Object.defineProperty(this.$, key, {
get() {
const { beforeEach, afterEach, setTo, setLockKey, setFrom } = router;
const pageArr = getCurrentPages();
const currPath = pageArr[pageArr.length - 1]?.$page.fullPath;
initPageApis.includes(key) &&
!navigateApis.includes(router.lockKey) &&
setLockKey(key);
showApis.includes(key) &&
initPageApis.includes(router.lockKey) &&
setLockKey("");
if (!isSameRoute(currPath, router.from) && !router.lockKey) {
if (beforeEach(currPath, router.from)) {
return [
() => {
afterEach(currPath, router.from);
setTo(currPath);
setFrom(currPath);
},
...originFun
];
}
return null;
}
showApis.includes(key) && setLockKey("");
return originFun;
}
});
});
}
});
export default {
beforeEach: (to, from) => {
console.log("before", to, from);
// uni.navigateTo('/pages/login/login')
return true;
},
afterEach: (to, from) => {
console.log("after", to, from);
},
to: null,
from: null,
lockKey: "",
setTo(to) {
this.to = to;
},
setFrom(from) {
this.from = from;
},
setLockKey(lockKey) {
this.lockKey = lockKey;
},
install(app) {
this.setFrom = this.setFrom.bind(this);
this.setTo = this.setTo.bind(this);
this.setLockKey = this.setLockKey.bind(this);
navigateApisProxy(this);
app.mixin(pageApisMixin(this));
}
};