Skip to content
  • P
    Projects
  • G
    Groups
  • S
    Snippets
  • Help

肖康 / H5_2.0

  • This project
    • Loading...
  • Sign in
Go to a project
  • Project
  • Repository
  • Issues 0
  • Merge Requests 0
  • Pipelines
  • Wiki
  • Snippets
  • Settings
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Files
  • Commits
  • Branches
  • Tags
  • Contributors
  • Graph
  • Compare
  • Charts
Find file
BlameHistoryPermalink
Switch branch/tag
  • H5_2.0
  • node_modules
  • uni-simple-router
  • appRouter
  • util.js
  • 肖康's avatar
    first init · ddbafbda
    肖康 committed 2 years ago
    ddbafbda
util.js 7.39 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
import { err } from '../helpers/warn';
import { copyObject, parseQuery } from '../helpers/util';
import { Global, route as mergeRoute } from '../helpers/config';

/**
 * 触发指定生命钩子
 * @param {Array} funList	//需要执行的方法列表
 * @param {Object} args //触发生命钩子传递的参数
 */
export const callAppHook = function (funList = [], args) {
    for (let i = 0; i < funList.length; i += 1) {
        funList[i].call(this, args);
    }
};
/**
 * @param {Number} index //需要获取的页面下标 -2:表示获取最后一个即当前页面 -1:表示全部 -3:当前页面的前一个页面
 * @param {Boolean} all //是否获取全部的页面
 */
export const getPages = function (index = -1, all) {
    const pages = getCurrentPages(all);
    if (index === -1) {
        return pages;
    }
    if (index === -2) {
        return pages[pages.length - 1];
    }
    if (index === -3) {
        return pages[pages.length - 2];
    }
    return pages[index];
};
/**
 * 验证当前页面是否为nvue页面
 * @param {Object} page 当前页面对象
 */
export const isNvuePage = function (page) {
    const cstr = page.constructor.name;
    const pageType = {
        s: true,
        z: false,
    };
    return pageType[cstr];
};

/**
 * @param {Object} page //当前顶级页面对象
 * @param {Object} vim:? //是否获取 $vm 对象还是 $mp 对象
 */
export const getPageVmOrMp = function (page, vim = true) {
    if (vim) {
        return page.$vm;
    }
    if (page.$vm.$mp) {
        return page.$vm.$mp;
    }
    if (isNvuePage(page)) {	// nvue 页面
        return {
            page,
            query: page.__displayReporter.query,
        };
    }
};

/**
 * 获取 to 的配置参数
 * @param {Object} rule 当前跳转的规则
 */
export const formatTo = function (finalRoute) {
    const route = copyObject(finalRoute.route);
    const { rule } = finalRoute;
    route.query = rule.query || rule.params || {};
    return route;
};
/**
 * 通过一个未知的路径或者名称 在路由表中查找指定路由表 并返回
 * @param {string} type   //path 或者 name
 * @param {Object} routes //当前对象的所有路由表
 */
export const pathOrNameToRoute = function (type, routes = Global.Router.CONFIG.routes) {
    const routesKeys = Object.keys(routes);
    for (let i = 0; i < routesKeys.length; i += 1) {
        const key = routesKeys[i];
        const item = routes[key];
        if (item.path === `/${type}`) {
            return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
        }
        if (item.path === type) {
            return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
        }
        if (item.name == type) {
            return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
        }
    }
    err(`当前 '${type}' 在路由表中没有找到匹配的 name 或者 path`);
};
/**
 * 统一格式话 路由传递的参数 看看是编码还是非编码 做相应的对策
 *
 * @param {Object} query 当前的路由参数
 * @param {Boolean} getter 是从页面获取 route 对象下的参数 还是编码后传输
 */
export const getFormatQuery = function (query = {}) {
    if (Global.Router.CONFIG.encodeURI) {
        try {
            query = JSON.parse(decodeURIComponent(query.query || encodeURIComponent('{}')));
        } catch (e) {
            query = JSON.parse(query.query);
        }
    }
    return query;
};
/**
 * 获取 from 的配置参数 from 页面永远都是站在当前页面忘其它地方走 所以都是最后一个页面
 *
 * @param {Object} routes //当前对象的所有路由表
 */
export const formatFrom = function (routes) {
    const topPage = getPages(-2);
    const { page, query } = getPageVmOrMp(topPage, false);
    const route = pathOrNameToRoute(page.route, routes);	// 获取到当前路由表下的 route
    route.query = getFormatQuery(query);	// 不管是编码传输还是非编码 最后都得在 to/from 中换成json对象
    return route;
};
/**
 *
 * 把用户的跳转路由规则格式化成uni-app可用的路由跳转规则
 *
 * @param {Object} rule  //当前用户跳转的路由规则
 * @param {Object} routes //当前simple-router 下的路由表
 */
export const ruleToUniNavInfo = function (rule, routes) {
    if (rule == null) {
        return err('当前跳转规则为空,请检查跳转代码');
    }
    // eslint-disable-next-line
    let [navType, route, query, animation] = ['path', null, {}, {}];
    if (rule.constructor === String) {		// 是字符串类型 那当前就是路径啦
        route = pathOrNameToRoute(rule, routes);	// 直接把 rule 当 path 传递 完事
    } else if (rule.constructor === Object) {		// 对象类型 可以是 path 或者 name
        route = pathOrNameToRoute(rule.path || (navType = 'name', rule.name), routes);	// 两则必有其一 报错自己处理
        query = rule.query || rule.params || {};
        animation = rule.animation || {};
    } else {
        return err('传的什么乱七八糟的类型?路由跳转规则只认字符串 \'path\' , 对象 \'path\' , 对象 \'name\' ');
    }
    animation = { ...Global.Router.CONFIG.APP.animation, ...route.animation || {}, ...animation };	// 合并多种方式声明的动画效果
    route.animation = animation;	// 这才是最终的页面切换效果
    // 路径处理完后   开始格式化参数
    const uniRoute = parseQuery(route.path, query);	// uni-app 需要的跳转规则
    return {
        rule,
        route,
        uniRoute,
    };
};
/**
 * 获取当前页面下的 Route 信息
 *
 * @param {Object} pages 获取页面对象集合
 * @param {Object} Vim 用户传递的当前页面对象
 */
export const APPGetPageRoute = function (pages, Vim) {
    let [query, path] = [{}, ''];
    const page = pages[pages.length - 1];	// 获取到当前页面
    if (pages.length > 0) {
        query = getFormatQuery(page.options, true);
        path = page.route;
    } else if (Vim != null) {
        query = getFormatQuery(Vim.$mp.page.options, true);
        path = page.route;
    }
    const route = pathOrNameToRoute(path);
    route.query = query;
    return route;
};
/**
 * 获取当前页面下的 onBeforeBack 生命周期并执行
 *
 * @param {Object} args 当前返回页面时uni-app传递的参数
 */
export const getPageOnBeforeBack = function (args) {
    return new Promise(async (resolve) => {
        const currPage = getPages(-2);	// 获取到当前页面
        const { onBeforeBack } = currPage.$vm.$options;
        if (onBeforeBack != null && onBeforeBack.constructor === Function) {
            const isNext = await onBeforeBack.call(currPage.$vm, args);
            if (isNext === true) {
                return resolve(false);
            }
        }
        return resolve(true);
    });
};
/**
 * 断言当前页面是否可返回上一级
 * @param {Object} page 当前页面webview对象
 */
export const assertCanBack = function (page) {
    const pageStyle = page.$getAppWebview().getStyle();
    if (pageStyle.titleNView != null && pageStyle.titleNView.autoBackButton) {	// 只有处理有带返回按钮的页面
        return true;
    }
    // 两种情况 1.真的是顶级页面时  2.自定义头部
    const { $page } = page;
    if ($page && $page.meta.isQuit === false) {		// 自定义头部 不是顶级页面
        return true;
    }
    return false;	// 不可返回 真的是顶级页面时 返回就直接退出app了
};