说明
- 初始版本方法,可能因为能力原因存在不足,请见谅,有问题评论区~~
- 主要通过
uni.addInterceptor
api进行路由拦截
- 目前小程序上面对于uniapp提供的路由跳转方式可以实现拦截,自带的返回按钮,底部tabbar切换无法拦截他们的跳转,但是可以监听到to和from
- h5支持路由全部拦截
- 支持vue2、vue3
- 通过
this.$Route
或者const {proxy}=getCurrentInstance();proxy.$Route
可以拿到当前页面的路由信息
- 目前测试了h5、微信小程序、支付宝小程序、抖音小程序、安卓app。其他的待测试
pages.json 配置:
"pages":{
{
"path": "pages/user/index",
"style": {
"disableScroll": true
},
"needLogin":true,
"name":"xxx",
"meta":{
}
}
}
vue2使用方法:
import addInterceptor from '@/addInterceptor.js'
addInterceptor((to, from, next)=>{
console.log(to, '----to----')
console.log(from, '----from----')
next()
},{
global:Vue,
globalObject:Vue.prototype,
routerVariable:['path','meta','name','needLogin'],
indexPath:'/pages/index/index'
})
this.$Route
vue3使用方法:
import addInterceptor from '@/addInterceptor.js'
export function createApp() {
const app = createSSRApp(App)
addInterceptor((to, from, next)=>{
console.log(to, '----to----')
console.log(from, '----from----')
next()
},{
global:app,
globalObject:app.config.globalProperties,
routerVariable:['path','meta','name','needLogin'],
indexPath:'/pages/index/index'
})
return {
app
}
}
import {
getCurrentInstance } from 'vue'
import {
onLoad} from '@dcloudio/uni-app';
setup(props, context) {
const {
proxy}=getCurrentInstance()
onLoad(()=>{
console.log(proxy.$Route)
})
return {
}
}
返回参数示例:
- 代码示例:
addInterceptor((to, from, next)=>{
console.log(to, '----to----')
console.log(from, '----from----')
if(to.needLogin){
next(()=>{
uni.switchTab({
url:'/pages/user/index'
})
})
}else{
next()
}
},{
global:Vue,
globalObject:Vue.prototype,
routerVariable:['path','meta','name','needLogin'],
indexPath:'/pages/index/index'
})
![在这里插入图片描述](https://img-blog.csdnimg.cn/aae7972b5aa940ffbd260919fdc5f59c.png)
核心方法addInterceptor.js
import defaultPage from"@/pages.json";export default function addInterceptor(t,e){
const a=uni.getSystemInfoSync().uniPlatform,{
global:l,routerVariable:r=["path"],indexPath:u,globalObject:n=null}=e;-1==r.indexOf("path")&&r.push("path");const o={
id:0};let p=!1,h="",i={
},g=null;const{
routerArray:s,tabBarList:c}=function(){
const{
pages:t,subPackages:e,tabBar:a}=defaultPage,l=[];function u(t,e=""){
t.forEach(t=>{
const a={
};r.forEach(l=>{
t[l]&&(a[l]="path"==l?e+"/"+t[l]:t[l])}),l.push(a)})}u(t),e.forEach(t=>{
u(t.pages,"/"+t.root)});let n=a?a.list:[];return n=n.map(t=>"/"+t.pagePath),{
routerArray:l,tabBarList:n}}();function f(e,a){
e.path="/"!=e.path.slice(0,1)?"/"+e.path:e.path,a.path="/"!=a.path.slice(0,1)?"/"+a.path:a.path;const l=s.find(t=>t.path==e.path);-1!=c.indexOf(e.path)&&(l.isTabBar=!0);const r=s.find(t=>t.path==a.path);-1!=c.indexOf(a.path)&&(r.isTabBar=!0),t(Object.assign({
},e,l),Object.assign({
},a,r),P)}function P(t=null){
if(t)"web"==a&&(p||history.back()),setTimeout(()=>{
t()},0);else if(p=!0,""!=h){
if("web"!=a&&"app"!=a||setTimeout(()=>{
p=!1},100),"web"!=a&&"app"!=a){
(0,uni[h])({
url:i.url,complete:()=>{
setTimeout(()=>{
p=!1},100)}})}}else p=!1}function b(t=0){
return new Promise((e,l)=>{
const r=getCurrentPages();let n=null,p={
};try{
"web"==a&&(n=(p=r[r.length-1])?p.__page__||{
url:p.$page.fullPath}:{
url:u}),"web"!=a&&(n={
url:(p=r[r.length-1]).$page?p.$page.fullPath:u})}catch(t){
n={
url:u}}0==t?(o.prvPage=n,e(!0)):e(n)})}function d(t,e){
let a=t;if("/"==a&&(a=u),!a||""==a)return;var l=[],r=a.split("?"),n=r.length>1?r[1]:"";l.push(...n.split("&")),l=l.filter(t=>""!=t);const o={
};for(var p=0;p<l.length;p++){
var h=l[p].split("=");o[h[0]]=h[1]}return e?!(!o[e]||""==o[e])&&{
url:r[0],obj:o[e]}:{
url:r[0],obj:o}}l.mixin({
onShow(){
o.id=(new Date).getTime()+"_"+parseInt(1e4*Math.random())}}),n&&(n.$Route={
},Object.defineProperty(n,"$Route",{
get(){
const t=getCurrentPages();let e=null,l={
};try{
"web"==a&&(e=(l=t[t.length-1])?l.__page__||{
fullPath:l.$page.fullPath}:{
fullPath:u}),"web"!=a&&(e={
fullPath:(l=t[t.length-1]).$page?l.$page.fullPath:u})}catch(t){
e={
fullPath:u}}const r=d(e.fullPath),n=s.find(t=>t.path==r.url);return n.query=r.obj,n}})),Object.defineProperty(o,"id",{
set(t){
g&&clearTimeout(g),g=setTimeout(async()=>{
try{
if(p)p=!1,await b();else{
const t=getCurrentPages();let e=null;"web"==a&&(e=t[t.length-1].__page__||{
url:t[t.length-1].$page.fullPath}),"web"!=a&&(e={
url:t[t.length-1].$page.fullPath});const l={
path:e.route||d(e.url).url,query:e.options||d(e.url).obj};o.prvPage&&(o.prvPage.route||o.prvPage.url||o.prvPage.fullPath)||await b(),f(l,{
path:o.prvPage.route||d(o.prvPage.url||o.prvPage.fullPath).url,query:o.prvPage.options||d(o.prvPage.url||o.prvPage.fullPath).obj}),await b()}}catch(t){
}},0)}});["navigateTo","redirectTo","switchTab","navigateBack","reLaunch"].forEach(t=>{
uni.addInterceptor(t,{
invoke(e){
if("app"==a&&"navigateBack"==t){
const t=getCurrentPages();let e=null,a={
};const l=(e={
url:(a=t[t.length-1]).$page?a.$page.fullPath:u}).url.split("?")[0];-1!=c.indexOf(l)&&(p=!0,setTimeout(()=>{
p=!1},100))}return p||function(t,e){
h=e,i=t;const l=getCurrentPages();let r=l[l.length-1],n=t,o={
};if("web"==a&&(o=r.__page__||{
url:r.$page.fullPath}),"web"!=a)try{
o={
url:r.$page.fullPath}}catch(t){
o={
url:u}}if("navigateBack"==e||"backbutton"==t.from){
let t=1;"backbutton"==i.from&&(t=1),i.delta&&(t=i.delta),"web"==a&&(n=l[l.length-(1+t)].__page__||{
url:l[l.length-(1+t)].$page.fullPath}),"web"!=a&&(n={
url:l[l.length-(1+t)].$page.fullPath})}f({
path:n.route||d(n.url).url,query:n.options||d(n.url).obj},{
path:o.route||d(o.url).url,query:o.options||d(o.url).obj})}(e,t),p},complete(){
h=""}})})};
具体详细的addInterceptor.js代码