123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- import { warn, err } from '../helpers/warn';
- import {
- diffRouter, vueDevRouteProxy, getRouterNextInfo, formatUserRule, nameToRute, encodeURLQuery, strPathToObjPath, getPages,
- } from './util';
- import { formatURLQuery } from '../helpers/util';
- import { vuelifeHooks, vueMount } from './base';
- import { lifeCycle, Global } from '../helpers/config';
- let beforeEachCount = 0;
- let afterEachCount = 0;
- let resolveLaunch = null;
- let beforeEnterDep = [];
- const beforeEachLaunch = new Promise((resolve) => resolveLaunch = resolve);
- export const appMount = function () {
- if (vueMount.length == 0) {
- return err('检测到您未进行dom模型挂载操作,请调用api\r\n\r\n RouterMount(Vim: any, el: any): void');
- }
- const {
- Vim,
- el,
- } = vueMount[0];
- let formatEl = el;
- if (el == null) {
- formatEl = '#app';
- }
- try {
- Vim.$mount(formatEl);
- } catch (error) {
- warn(`挂载vue节点时错误啦${error}`);
- }
- };
- export const forMatNext = function (to, Intercept, next, Router) {
- const { CONFIG, selfRoutes } = Router;
- if (CONFIG.h5.vueRouterDev) {
- next(Intercept);
- return Intercept;
- }
- if (typeof Intercept === 'object') {
- const navType = Reflect.get(Intercept, 'NAVTYPE');
- delete Intercept.NAVTYPE;
- if (navType == 'push') {
- Intercept.replace = false;
- Intercept.type = 'navigateTo';
- } else {
- Intercept.replace = true;
- Intercept.type = 'reLaunch';
- }
- const name = Reflect.get(Intercept, 'name');
- Intercept.query = Intercept.params || Intercept.query;
- delete Intercept.name;
- delete Intercept.params;
- if (Intercept.query == null) {
- Intercept.query = {};
- }
- if (name != null) {
- const { aliasPath, path } = nameToRute(name, selfRoutes);
- Intercept.path = aliasPath || path;
- } else {
- Intercept.path = Reflect.get(Intercept, 'path');
- const rute = formatUserRule(Intercept.path, selfRoutes, CONFIG);
- if (rute == null) {
- return false;
- }
- Intercept.path = rute;
- }
- if (CONFIG.encodeURI) {
- const query = encodeURIComponent(JSON.stringify(Intercept.query));
- const formatQuery = formatURLQuery(query);
- Intercept.query = {};
- if (formatQuery != '') {
- Intercept.query.query = formatQuery;
- }
- }
- } else if (Intercept != null && Intercept.constructor === String) {
- Intercept = formatUserRule(Intercept, selfRoutes, CONFIG);
- }
- let objPath = Intercept;
- if (Intercept != null && Intercept.constructor !== Boolean) {
- objPath = strPathToObjPath(Intercept);
- if (objPath != null) {
- const type = Reflect.get(objPath, 'type');
- if (type == null) {
- objPath.type = 'navigateTo';
- }
- }
- } else if (Intercept === false) {
- Router.lifeCycle.routerAfterHooks[0].call(Router, { H5Intercept: true });
- }
- next(objPath);
- return Intercept;
- };
- const beforeRouteLeaveHooks = function (to, from, next, Router) {
- return new Promise((resolve) => {
- const { currentRoute } = Router.$route;
- if (currentRoute.path == to.path) {
- return resolve();
- }
- const page = getPages();
- if (page == null || page._HHYANGbeforeRouteLeaveCalled) {
- warn('当前环境下无须执行 beforeRouteLeave。 原因:1.page等于null 2.真的的无须执行');
- return resolve();
- }
- const beforeRouteLeaveArray = page.$options.beforeRouteLeave;
- if (beforeRouteLeaveArray == null) {
- return resolve();
- }
- const { toRoute, fromRoute } = getRouterNextInfo(to, from, Router);
- const beforeRouteLeave = beforeRouteLeaveArray[0];
- beforeRouteLeave.call(page, toRoute, fromRoute, (Intercept) => {
- if (Intercept == null) {
- return resolve();
- }
- page._HHYANGbeforeRouteLeaveCalled = true;
- forMatNext(to, Intercept, next, Router);
- });
- });
- };
- export const beforeEnterHooks = function (to, from, next, userHooks, Router) {
- return new Promise(async (resolve) => {
-
- if (beforeEnterDep.includes(to.path)) {
- next();
- return resolve();
- }
- beforeEnterDep = [to.path];
- if (Reflect.get(Router, 'H5RouterReady')) {
- const res = await new Promise(async (resolveNext) => {
- const {
- toRoute,
- fromRoute,
- } = getRouterNextInfo(to, from, Router);
- await userHooks(toRoute, fromRoute, resolveNext);
- });
- forMatNext(to, res, next, Router);
- } else {
- next();
- }
- resolve();
- });
- };
- export const afterHooks = async function (to, from, next, Router) {
- vuelifeHooks.afterHooks[0](to, from);
- if (lifeCycle.afterHooks[0]) {
- if (afterEachCount === 0) {
- await beforeEachLaunch;
- appMount(Router);
- }
- const {
- toRoute,
- fromRoute,
- } = getRouterNextInfo(to, from, Router);
- lifeCycle.afterHooks[0](toRoute, fromRoute);
- } else if (afterEachCount === 0) {
- appMount(Router);
- }
- afterEachCount += 1;
- Router.lifeCycle.routerAfterHooks[0].call(Router);
- };
- export const beforeHooks = function (to, from, next, Router) {
- return new Promise(async (resolve) => {
- await Router.lifeCycle.routerbeforeHooks[0].call(Router);
- await beforeRouteLeaveHooks(to, from, next, Router);
- const H5 = Router.CONFIG.h5;
- vuelifeHooks.beforeHooks[0](to, from, async (Intercept) => {
- if (Intercept != null && H5.keepUniIntercept === true && H5.vueRouterDev === false) {
- next(Intercept);
- warn('uni-app 内部强制触发跳转拦截');
- beforeEachCount += 1;
- return resolve();
- }
-
- if (!lifeCycle.beforeHooks[0]) {
- next();
- beforeEachCount += 1;
- resolveLaunch();
- return resolve();
- }
- const res = await new Promise(async (resolveNext) => {
- const {
- toRoute,
- fromRoute,
- } = getRouterNextInfo(to, from, Router);
- await lifeCycle.beforeHooks[0](toRoute, fromRoute, resolveNext);
- });
- const beforeIntercept = forMatNext(to, res, next, Router);
- if (beforeEachCount == 0 && beforeIntercept == null && to.meta.isTabBar) {
- const {
- selfRoutes,
- } = Router;
- const beforeEnter = Reflect.get(selfRoutes[`/${to.meta.pagePath}`], 'beforeEnter');
- if (beforeEnter) {
- await beforeEnterHooks(to, from, next, beforeEnter, Router);
- }
- }
- beforeEachCount += 1;
- resolveLaunch();
- resolve();
- });
- });
- };
- export const triggerLifeCycle = function (Router, vueRouter) {
- const { CONFIG } = Router;
- const currRoute = vueRouter.currentRoute;
- if (vueRouter.mode === 'hash') {
- const {
- query,
- path,
- } = currRoute;
- const URLQuery = encodeURLQuery(CONFIG, query, 'hash');
- vueRouter.replace(`${path}${URLQuery}`);
- } else {
- const {
- toRoute,
- } = getRouterNextInfo(currRoute, currRoute, Router);
- const URLQuery = encodeURLQuery(CONFIG, currRoute.query, 'history');
- vueRouter.replace({
- path: toRoute.aliasPath || toRoute.path || currRoute.path,
- query: URLQuery,
- type: 'redirectTo',
- });
- }
- };
- export const registerRouter = function (Router, vueRouter, vueRouterDev) {
- let routeMap = [];
- if (!vueRouterDev) {
- routeMap = diffRouter(Router, vueRouter, Router.CONFIG.h5.useUniConfig);
- } else {
- routeMap = vueDevRouteProxy(Router.CONFIG.routes, Router);
- }
- const createRouter = () => new vueRouter.constructor({
- base: vueRouter.options.base,
- mode: vueRouter.options.mode,
- routes: routeMap,
- });
- const router = createRouter();
- vueRouter.matcher = router.matcher;
- Global.vueRouter = vueRouter;
- Global.RouterReadyPromise();
- Router.H5RouterReady = true;
-
- setTimeout(() => {
- triggerLifeCycle(Router, vueRouter);
- });
- };
|