util.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import { Global, route as mergeRoute } from '../helpers/config';
  2. import { copyObject, parseQuery } from '../helpers/util';
  3. import { err } from '../helpers/warn';
  4. import { baiduApple, touTiao } from '../helpers/compile';
  5. /**
  6. * 触发指定生命钩子
  7. * @param {Array} funList //需要执行的方法列表
  8. * @param {Object} args //触发生命钩子传递的参数
  9. */
  10. export const callAppHook = function (funList, args) {
  11. for (let i = 0; i < funList.length; i += 1) {
  12. funList[i].call(this, args);
  13. }
  14. };
  15. /**
  16. * @param {Object} page //当前顶级页面对象
  17. * @param {Object} vim:? //是否获取 $vm 对象还是 $mp 对象
  18. */
  19. export const getPageVmOrMp = function (page, vim = true) {
  20. if (vim) {
  21. return page.$vm;
  22. }
  23. const { $mp } = page.$vm;
  24. baiduApple(() => { // 百度小程序新增一个route属性
  25. $mp.page.route = $mp.page.is;
  26. });
  27. touTiao(() => { // 头条小程序新增一个route属性
  28. $mp.page.route = $mp.page.is;
  29. });
  30. return $mp;
  31. };
  32. /**
  33. * 统一格式话 路由传递的参数 看看是编码还是非编码 做相应的对策
  34. *
  35. * @param {Object} query 当前的路由参数
  36. * @param {Boolean} getter 是从页面获取 route 对象下的参数 还是编码后传输
  37. */
  38. export const getFormatQuery = function (query = {}, getter = false) {
  39. if (Global.Router.CONFIG.encodeURI) {
  40. if (getter) {
  41. try { // 除去微信小程序都不需要 decodeURIComponent
  42. query = JSON.parse(decodeURIComponent(query.query) || '{}');
  43. } catch (e) { // 其他小程序
  44. query = JSON.parse(query.query || '{}');
  45. }
  46. } else {
  47. try {
  48. query = JSON.parse(decodeURIComponent(query.query || encodeURIComponent('{}')));
  49. } catch (e) {
  50. query = JSON.parse(query.query);
  51. }
  52. }
  53. }
  54. return query;
  55. };
  56. /**
  57. * @param {Number} index //需要获取的页面下标 -2:表示获取最后一个即当前页面 -1:表示全部 -3:当前页面的前一个页面
  58. * @param {Boolean} all //是否获取全部的页面
  59. */
  60. export const getPages = function (index = -1, all) {
  61. const pages = getCurrentPages(all);
  62. if (index === -1) {
  63. return pages;
  64. }
  65. if (index === -2) {
  66. return pages[pages.length - 1];
  67. }
  68. if (index === -3) {
  69. return pages[pages.length - 2];
  70. }
  71. return pages[index];
  72. };
  73. /**
  74. * 通过一个未知的路径或者名称 在路由表中查找指定路由表 并返回
  75. * @param {string} type //path 或者 name
  76. * @param {Object} routes //当前对象的所有路由表
  77. */
  78. export const pathOrNameToRoute = function (type, routes = Global.Router.CONFIG.routes) {
  79. const routesKeys = Object.keys(routes);
  80. for (let i = 0; i < routesKeys.length; i += 1) {
  81. const key = routesKeys[i];
  82. const item = routes[key];
  83. if (item.path === `/${type}`) {
  84. return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
  85. }
  86. if (item.path === type) {
  87. return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
  88. }
  89. if (item.name == type) {
  90. return mergeRoute(item); // 合并一下对象,主要是合并 query:{} 及 params:{}
  91. }
  92. }
  93. err(`当前 '${type}' 在路由表中没有找到匹配的 name 或者 path`);
  94. };
  95. /**
  96. * 获取 to 的配置参数
  97. * @param {Object} rule 当前跳转的规则
  98. */
  99. export const formatTo = function (finalRoute) {
  100. const route = copyObject(finalRoute.route);
  101. const { rule } = finalRoute;
  102. route.query = rule.query || rule.params || {};
  103. return route;
  104. };
  105. /**
  106. * 获取 from 的配置参数 from 页面永远都是站在当前页面忘其它地方走 所以都是最后一个页面
  107. *
  108. * @param {Object} routes //当前对象的所有路由表
  109. */
  110. export const formatFrom = function (routes) {
  111. const topPage = getPages(-2);
  112. const { page, query } = getPageVmOrMp(topPage, false);
  113. const route = pathOrNameToRoute(page.route, routes); // 获取到当前路由表下的 route
  114. route.query = getFormatQuery(query); // 不管是编码传输还是非编码 最后都得在 to/from 中换成json对象
  115. return route;
  116. };
  117. /**
  118. *
  119. * 把用户的跳转路由规则格式化成uni-app可用的路由跳转规则
  120. *
  121. * @param {Object} rule //当前用户跳转的路由规则
  122. * @param {Object} routes //当前simple-router 下的路由表
  123. */
  124. export const ruleToUniNavInfo = function (rule, routes) {
  125. if (rule == null) {
  126. return err('当前跳转规则为空,请检查跳转代码');
  127. }
  128. // eslint-disable-next-line
  129. let [navType, route, query] = ['path', null, {}];
  130. if (rule.constructor === String) { // 是字符串类型 那当前就是路径啦
  131. route = pathOrNameToRoute(rule, routes); // 直接把 rule 当 path 传递 完事
  132. } else if (rule.constructor === Object) { // 对象类型 可以是 path 或者 name
  133. route = pathOrNameToRoute(rule.path || (navType = 'name', rule.name), routes); // 两则必有其一 报错自己处理
  134. query = rule.query || rule.params || {};
  135. } else {
  136. return err('传的什么乱七八糟的类型?路由跳转规则只认字符串 \'path\' , 对象 \'path\' , 对象 \'name\' ');
  137. }
  138. // 路径处理完后 开始格式化参数
  139. const uniRoute = parseQuery(route.path, query); // uni-app 需要的跳转规则
  140. return {
  141. rule,
  142. route,
  143. uniRoute,
  144. };
  145. };
  146. /**
  147. * 获取当前页面下的 Route 信息
  148. *
  149. * @param {Object} pages 获取页面对象集合
  150. * @param {Object} Vim 用户传递的当前页面对象
  151. */
  152. export const AppletsPageRoute = function (pages, Vim) {
  153. let [query, path] = [{}, ''];
  154. const page = pages[pages.length - 1]; // 获取到当前页面
  155. if (pages.length > 0) {
  156. const uniQuery = getPageVmOrMp(page, false).query;
  157. query = getFormatQuery(uniQuery, true);
  158. path = page.route;
  159. } else if (Vim != null) {
  160. query = getFormatQuery(Vim.$mp.page.options, true);
  161. path = page.route;
  162. }
  163. const route = pathOrNameToRoute(path);
  164. route.query = query;
  165. return route;
  166. };