基于mpvue-router-patch实现路由拦截
目录本文目的在于记录mpvue-router-patch-interceptor的实现过程,基于mpvue-router-patch,以及我以前的两篇博客:JavaScript异步函数同步方法 和
·
目录
本文目的在于记录mpvue-router-patch-interceptor的实现过程,基于mpvue-router-patch,以及我以前的两篇博客:JavaScript异步函数同步方法 和 基于koa2中间件原理实现拦截任意对象方法的调用,实现mpvue的页面路由跳转拦截器,这个我已经发布到npm上去了,就叫做mpvue-router-patch-interceptor,由于我自己在测试的时候,发现如果使用mpvue-entry这个插件,我这个就用不了了,提示在mpvue-entry生成的js文件中找不到mpvue-router-patch-interceptor,具体原因我还在找,不过同学们可以直接从这里讲源码拿去用,代码不多。
源码
/*
* creator: weishengjian
* time: 2018.7.15 16:41
*/
import MpvueRouterPatch from 'mpvue-router-patch'
import {pushArray} from "./utils";
let $router; //mpvue-router-patch插件注册的$router对象
let $push; //mpvue-router-patch插件注册的$router.push方法
let everyMiddlewares = []; //全局中间件,拦截所有路由跳转
let matchMiddlewares = {}; //路由地址匹配中间件,key为匹配路径的正则表达式字符串、value为中间件数组
/*
* 页面跳转中间件,执行页面跳转动作
*/
async function pushMiddware(...args) {
// console.log('into original push middlewares')
$push(...args);
}
/*
* 合并异步中间件方法
*/
function compose(middlewares) { //异步中间件同步方法
return function (...args) {
function dispatch(i) {
let fn = middlewares[i];
if (!fn) {
return Promise.resolve();
}
else {
return Promise.resolve(fn(
...args,
function next() {
return dispatch(i + 1)
}
))
}
}
return dispatch(0);
}
}
function getMatchMiddlewares(path) {
let ret = [];
for (let regexp in matchMiddlewares) {
// console.log(regexp, path, new RegExp(regexp).test(path))
if (new RegExp(regexp).test(path))
pushArray(ret, matchMiddlewares[regexp])
}
return ret;
}
let MpvueRouterPatchInterceptor = {
install(Vue, {every, match}) {
Vue.use(MpvueRouterPatch);
console.log('Vue.prototype.$router', Vue.prototype.$router)
$router = Vue.prototype.$router
$push = $router.push
pushArray(everyMiddlewares, every)
matchMiddlewares = Object.assign({}, match)
/*重写mpvue-router-patch的$router.push方法*/
$router.push = async (...args) => {
// console.log('push start-->>', args)
let option = typeof args[0] === 'string' ? {path: args[0]} : args[0]
let fn = compose(everyMiddlewares.concat(getMatchMiddlewares(option.path)).concat([pushMiddware]));
fn(option);
// console.log('push end')
}
},
every(everyMiddleware) {
everyMiddlewares.push(everyMiddleware)
},
match(regexp, middleware) {
(!matchMiddlewares[regexp]) && (matchMiddlewares[regexp] = [])
matchMiddlewares[regexp].push(middleware)
},
sayHello() {
console.log('hello')
},
}
export default MpvueRouterPatchInterceptor
utils文件代码
export function pushArray(targetArray, dataArray) {
if (!dataArray) return
if (!dataArray instanceof Array) {
console.error('dataArray的参数必须是一个数组');
return;
}
dataArray.forEach((item) => {
targetArray.push(item);
})
}
用法:
在mpvue工程src/main.js中
import MpvueRouterPatchInterceptor from "./common/mpvue-router-patch-interceptor";
import {every, match} from "./common/router-interceptors";
Vue.use(MpvueRouterPatchInterceptor, {every, match});
其中every和match是自定义的拦截器,every为拦截所有路由,match为拦截正则表达式匹配的路由,every为数组,match为对象,实例代码:
/*
* power by weishengjian
* datetime 2018/7/14 10:32
* desc: 页面跳转路由拦截器
*/
import {hideLoading, showLoading, showModal} from "./msg";
import {delay} from "./mpvue-router-patch-interceptor";
export let every = [
async (option, next) => {
console.log('1 start')
showLoading()
await delay(100)
await next();
hideLoading()
console.log('1 end')
},
async (option, next) => {
console.log('2 start')
await delay(200)
await next()
console.log('2 end')
},
async (option, next) => {
console.log('3 start')
await delay(300)
await next()
console.log('3 end')
}
]
export let match = {
'/pages': [
async (option, next) => {
console.log('match /pages', option)
next()
}
],
'/pages/dev': [
async (option, next) => {
console.log('match /pages/dev', option)
if (option.query.name !== '111') {
showModal('name 不为111');
} else {
next()
}
}
]
}
更多推荐
已为社区贡献13条内容
所有评论(0)