util.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import { route, baseConfig, Global } from './config';
  2. import { builtIn } from '../vueRouter/base';
  3. import { err, log, warn } from './warn';
  4. /**
  5. * 当前是不是H5运行环境
  6. */
  7. export const isH5 = function () {
  8. return typeof window !== 'undefined' && typeof document !== 'undefined';
  9. };
  10. /**
  11. * 判断当前变量是否为Object
  12. * @param {Object} strObj
  13. */
  14. export const isObject = function (strObj) {
  15. return strObj.toString() === '[object Object]' && strObj.constructor === Object;
  16. };
  17. /**
  18. * 获取当前运行平台
  19. * @param {Boolean} applets 默认false true时所有小程序平台统一返回 APPLETS
  20. */
  21. export const appPlatform = function (applets = false) {
  22. let platform = '';
  23. // #ifdef APP-PLUS-NVUE
  24. platform = 'APPNVUE';
  25. // #endif
  26. // #ifdef APP-PLUS
  27. platform = 'APP';
  28. // #endif
  29. // #ifdef H5
  30. platform = 'H5';
  31. // #endif
  32. // #ifdef MP-ALIPAY
  33. platform = 'ALIPAY';
  34. // #endif
  35. // #ifdef MP-BAIDU
  36. platform = 'BAIDU';
  37. // #endif
  38. // #ifdef MP-QQ
  39. platform = 'QQ';
  40. // #endif
  41. // #ifdef MP-WEIXIN
  42. platform = 'WEIXIN';
  43. // #endif
  44. // #ifdef MP-TOUTIAO
  45. platform = 'TOUTIAO';
  46. // #endif
  47. if (applets) {
  48. // #ifdef MP
  49. platform = 'APPLETS';
  50. // #endif
  51. }
  52. return platform;
  53. };
  54. /**
  55. * 定义一个空方法 如果最后一个参数为true则打印所有参数
  56. * @param {...any} args
  57. */
  58. export const noop = function (...args) {
  59. if (args[args.length - 1] === true) {
  60. log(args);
  61. }
  62. };
  63. /**
  64. * 格式化基础配置信息 通过new Router传递过来的参数
  65. */
  66. export const formatConfig = function (userConfig) {
  67. if (!userConfig.routes || userConfig.routes.constructor !== Array) {
  68. return err(`路由参数 'routes' 必须传递 \r\n\r\n${JSON.stringify(userConfig)}`);
  69. }
  70. if (userConfig.h5 != null && userConfig.h5.constructor !== Object) {
  71. return err(`h5参数传递错误,应该是一个 'Object' 类型 示例:\r\n\r\n${JSON.stringify(baseConfig.h5)}`);
  72. }
  73. const config = Object.create(null);
  74. const baseConfigKeys = Object.keys(baseConfig);
  75. for (let i = 0; i < baseConfigKeys.length; i += 1) {
  76. const key = baseConfigKeys[i];
  77. if (userConfig[key] != null) {
  78. if (userConfig[key].constructor === Object) {
  79. config[key] = {
  80. ...baseConfig[key],
  81. ...userConfig[key],
  82. };
  83. } else if (key == 'routes') { // 需要加入已知的白名单
  84. config[key] = [...baseConfig[key], ...userConfig[key], ...builtIn];
  85. } else {
  86. config[key] = userConfig[key];
  87. }
  88. } else {
  89. config[key] = baseConfig[key];
  90. }
  91. }
  92. return config;
  93. };
  94. export const filter = function (str) {
  95. str += '';
  96. str = str.replace(/%/g, '%25');
  97. str = str.replace(/\+/g, '%2B');
  98. str = str.replace(/ /g, '%20');
  99. str = str.replace(/\//g, '%2F');
  100. str = str.replace(/\?/g, '%3F');
  101. str = str.replace(/&/g, '%26');
  102. str = str.replace(/=/g, '%3D');
  103. str = str.replace(/#/g, '%23');
  104. return str;
  105. };
  106. /**
  107. * 使用encodeURI:true的情况 需要进行编码后再传递,解码等等 可以传递深度对象并会在路径后面加入一个query=
  108. *
  109. * @param {String} routerName //路径名称
  110. * @param {JSON} query //需要格式化参数
  111. * @param {Boolean} Encode //是获取还是编码后传递
  112. */
  113. export const parseQueryN = function (routerName, query, Encode) {
  114. if (Encode) {
  115. return {
  116. url: routerName,
  117. query: JSON.parse(decodeURIComponent(query.replace(/^query=/, ''))),
  118. };
  119. }
  120. return {
  121. url: routerName,
  122. query: `query=${encodeURIComponent(JSON.stringify(query))}`,
  123. };
  124. };
  125. /**
  126. * 使用encodeURI:false的情况 直接格式化为普通的queryURl参数形式传递即可 扁平深度对象
  127. *
  128. * @param {String} routerName //路径名称
  129. * @param {JSON} query //需要格式化参数
  130. * @param {Boolean} Encode //是获取还是编码后传递
  131. */
  132. export const parseQueryD = function (routerName, query, Encode) {
  133. if (Encode) {
  134. const obj = {};
  135. const reg = /([^=&\s]+)[=\s]*([^&\s]*)/g;
  136. while (reg.exec(query)) {
  137. obj[RegExp.$1] = RegExp.$2;
  138. }
  139. return {
  140. url: routerName,
  141. query: obj,
  142. };
  143. }
  144. const encodeArr = [];
  145. const queryKeys = Object.keys(query);
  146. for (let i = 0; i < queryKeys.length; i += 1) {
  147. const attr = queryKeys[i];
  148. let encodeStr = '';
  149. if (query[attr].constructor == Object) {
  150. encodeStr = parseQueryD(routerName, query[attr], Encode).query;
  151. encodeArr.push(encodeStr);
  152. } else {
  153. encodeStr = filter(query[attr]);
  154. encodeArr.push(`${attr}=${encodeStr}`);
  155. }
  156. }
  157. return {
  158. url: routerName,
  159. query: encodeArr.join('&'),
  160. };
  161. };
  162. /**
  163. * @param {String} routerName //路径名称
  164. * @param {JSON} query //需要格式化参数
  165. * @param {Boolean} Encode //是获取还是编码后传递
  166. */
  167. export const parseQuery = function (routerName, query, Encode = false) {
  168. if (Global.Router.CONFIG.encodeURI) {
  169. return parseQueryN(routerName, query, Encode);
  170. }
  171. return parseQueryD(routerName, query, Encode);
  172. };
  173. export const exactRule = function (cloneRule, routes, ruleKey, getRule = false) {
  174. const params = {};
  175. let i = 0;
  176. // eslint-disable-next-line
  177. while (true) {
  178. const item = routes[i];
  179. if (item == null) {
  180. if (!getRule) {
  181. err(`路由表中未查找到 '${ruleKey}' 为 '${cloneRule[ruleKey]}'`);
  182. }
  183. return {
  184. path: '',
  185. name: '',
  186. };
  187. }
  188. if (item[ruleKey] != null && item[ruleKey] === cloneRule[ruleKey]) {
  189. if (!getRule) {
  190. params.url = item.path;
  191. params.rule = item;
  192. if (isH5()) { // 如果是h5 则使用优先使用自定义路径名称
  193. params.url = item.aliasPath || item.path;
  194. }
  195. return params;
  196. }
  197. return item;
  198. }
  199. i += 1;
  200. }
  201. };
  202. export const resolveRule = function (router, rule, query = {}, ruleKey = 'path') {
  203. const ruleInfo = route(
  204. exactRule({
  205. ...rule,
  206. },
  207. router.CONFIG.routes,
  208. ruleKey,
  209. router),
  210. );
  211. return {
  212. ...ruleInfo,
  213. query,
  214. };
  215. };
  216. /**
  217. * 把一些不必要的参数进行格式化掉,完成url的美观
  218. * @param {String} URLQuery URL中传递的参数
  219. */
  220. export const formatURLQuery = function (URLQuery) {
  221. switch (URLQuery.trim()) {
  222. case 'query=%7B%7D':
  223. case '%7B%7D':
  224. case '?query=%7B%7D':
  225. case '?':
  226. case '?[object Object]':
  227. case '?query={}':
  228. URLQuery = '';
  229. break;
  230. default:
  231. warn('url已经很完美啦,不需要格式化!');
  232. break;
  233. }
  234. return URLQuery;
  235. };
  236. /**
  237. * 拷贝对象
  238. * @param {Object} object
  239. */
  240. export const copyObject = function (object) {
  241. return JSON.parse(JSON.stringify(object));
  242. };