项目初始化
This commit is contained in:
185
sheep/router/index.js
Normal file
185
sheep/router/index.js
Normal file
@@ -0,0 +1,185 @@
|
||||
import $store from '@/sheep/store';
|
||||
import { showAuthModal, showShareModal } from '@/sheep/hooks/useModal';
|
||||
import { isNumber, isString, isEmpty, startsWith, isObject, isNil, clone } from 'lodash-es';
|
||||
import throttle from '@/sheep/helper/throttle';
|
||||
|
||||
const _go = (
|
||||
path,
|
||||
params = {},
|
||||
options = {
|
||||
redirect: false,
|
||||
},
|
||||
) => {
|
||||
let page = ''; // 跳转页面
|
||||
let query = ''; // 页面参数
|
||||
let url = ''; // 跳转页面完整路径
|
||||
|
||||
if (isString(path)) {
|
||||
// 判断跳转类型是 path | 还是http
|
||||
if (startsWith(path, 'http')) {
|
||||
// #ifdef H5
|
||||
window.location = path;
|
||||
return;
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
page = `/pages/public/webview`;
|
||||
query = `url=${encodeURIComponent(path)}`;
|
||||
// #endif
|
||||
} else if (startsWith(path, 'action:')) {
|
||||
handleAction(path);
|
||||
return;
|
||||
} else {
|
||||
[page, query] = path.split('?');
|
||||
}
|
||||
if (!isEmpty(params)) {
|
||||
let query2 = paramsToQuery(params);
|
||||
if (isEmpty(query)) {
|
||||
query = query2;
|
||||
} else {
|
||||
query += '&' + query2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isObject(path)) {
|
||||
page = path.url;
|
||||
if (!isNil(path.params)) {
|
||||
query = paramsToQuery(path.params);
|
||||
}
|
||||
}
|
||||
|
||||
const nextRoute = ROUTES_MAP[page];
|
||||
|
||||
// 未找到指定跳转页面
|
||||
// mark: 跳转404页
|
||||
if (!nextRoute) {
|
||||
console.log(`%c跳转路径参数错误<${page || 'EMPTY'}>`, 'color:red;background:yellow');
|
||||
return;
|
||||
}
|
||||
|
||||
// 页面登录拦截
|
||||
if (nextRoute.meta?.auth && !$store('user').isLogin) {
|
||||
showAuthModal();
|
||||
return;
|
||||
}
|
||||
|
||||
url = page;
|
||||
if (!isEmpty(query)) {
|
||||
url += `?${query}`;
|
||||
}
|
||||
|
||||
// 跳转底部导航
|
||||
if (TABBAR.includes(page)) {
|
||||
uni.switchTab({
|
||||
url,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用redirect跳转
|
||||
if (options.redirect) {
|
||||
uni.redirectTo({
|
||||
url,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.navigateTo({
|
||||
url,
|
||||
});
|
||||
};
|
||||
|
||||
// 限流 防止重复点击跳转
|
||||
function go(...args) {
|
||||
throttle(() => {
|
||||
_go(...args);
|
||||
});
|
||||
}
|
||||
|
||||
function paramsToQuery(params) {
|
||||
if (isEmpty(params)) {
|
||||
return '';
|
||||
}
|
||||
// return new URLSearchParams(Object.entries(params)).toString();
|
||||
let query = [];
|
||||
for (let key in params) {
|
||||
query.push(key + '=' + params[key]);
|
||||
}
|
||||
|
||||
return query.join('&');
|
||||
}
|
||||
|
||||
function back() {
|
||||
// #ifdef H5
|
||||
history.back();
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
uni.navigateBack();
|
||||
// #endif
|
||||
}
|
||||
|
||||
function redirect(path, params = {}) {
|
||||
go(path, params, {
|
||||
redirect: true,
|
||||
});
|
||||
}
|
||||
|
||||
// 检测是否有浏览器历史
|
||||
function hasHistory() {
|
||||
// #ifndef H5
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length > 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// #endif
|
||||
|
||||
// #ifdef H5
|
||||
return !!history.state.back;
|
||||
// #endif
|
||||
}
|
||||
|
||||
function getCurrentRoute(field = '') {
|
||||
let currentPage = getCurrentPage();
|
||||
// #ifdef MP
|
||||
currentPage.$page['route'] = currentPage.route;
|
||||
currentPage.$page['options'] = currentPage.options;
|
||||
// #endif
|
||||
if (field !== '') {
|
||||
return currentPage.$page[field];
|
||||
} else {
|
||||
return currentPage.$page;
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrentPage() {
|
||||
let pages = getCurrentPages();
|
||||
return pages[pages.length - 1];
|
||||
}
|
||||
|
||||
function handleAction(path) {
|
||||
const action = path.split(':');
|
||||
switch (action[1]) {
|
||||
case 'showShareModal':
|
||||
showShareModal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function error(errCode, errMsg = '') {
|
||||
redirect('/pages/public/error', {
|
||||
errCode,
|
||||
errMsg,
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
go,
|
||||
back,
|
||||
hasHistory,
|
||||
redirect,
|
||||
getCurrentPage,
|
||||
getCurrentRoute,
|
||||
error,
|
||||
};
|
79
sheep/router/utils/strip-json-comments.js
Normal file
79
sheep/router/utils/strip-json-comments.js
Normal file
@@ -0,0 +1,79 @@
|
||||
const singleComment = Symbol('singleComment');
|
||||
const multiComment = Symbol('multiComment');
|
||||
|
||||
const stripWithoutWhitespace = () => '';
|
||||
const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' ');
|
||||
|
||||
const isEscaped = (jsonString, quotePosition) => {
|
||||
let index = quotePosition - 1;
|
||||
let backslashCount = 0;
|
||||
|
||||
while (jsonString[index] === '\\') {
|
||||
index -= 1;
|
||||
backslashCount += 1;
|
||||
}
|
||||
|
||||
return Boolean(backslashCount % 2);
|
||||
};
|
||||
|
||||
export default function stripJsonComments(jsonString, { whitespace = true } = {}) {
|
||||
if (typeof jsonString !== 'string') {
|
||||
throw new TypeError(
|
||||
`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``,
|
||||
);
|
||||
}
|
||||
|
||||
const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
|
||||
|
||||
let isInsideString = false;
|
||||
let isInsideComment = false;
|
||||
let offset = 0;
|
||||
let result = '';
|
||||
|
||||
for (let index = 0; index < jsonString.length; index++) {
|
||||
const currentCharacter = jsonString[index];
|
||||
const nextCharacter = jsonString[index + 1];
|
||||
|
||||
if (!isInsideComment && currentCharacter === '"') {
|
||||
const escaped = isEscaped(jsonString, index);
|
||||
if (!escaped) {
|
||||
isInsideString = !isInsideString;
|
||||
}
|
||||
}
|
||||
|
||||
if (isInsideString) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isInsideComment && currentCharacter + nextCharacter === '//') {
|
||||
result += jsonString.slice(offset, index);
|
||||
offset = index;
|
||||
isInsideComment = singleComment;
|
||||
index++;
|
||||
} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
|
||||
index++;
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index);
|
||||
offset = index;
|
||||
continue;
|
||||
} else if (isInsideComment === singleComment && currentCharacter === '\n') {
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index);
|
||||
offset = index;
|
||||
} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
|
||||
result += jsonString.slice(offset, index);
|
||||
offset = index;
|
||||
isInsideComment = multiComment;
|
||||
index++;
|
||||
continue;
|
||||
} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
|
||||
index++;
|
||||
isInsideComment = false;
|
||||
result += strip(jsonString, offset, index + 1);
|
||||
offset = index + 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return result + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
|
||||
}
|
103
sheep/router/utils/uni-read-pages-v3.js
Normal file
103
sheep/router/utils/uni-read-pages-v3.js
Normal file
@@ -0,0 +1,103 @@
|
||||
'use strict';
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true,
|
||||
});
|
||||
const fs = require('fs');
|
||||
import stripJsonComments from './strip-json-comments';
|
||||
import { isArray, isEmpty } from 'lodash';
|
||||
|
||||
class TransformPages {
|
||||
constructor({ includes, pagesJsonDir }) {
|
||||
this.includes = includes;
|
||||
this.uniPagesJSON = JSON.parse(stripJsonComments(fs.readFileSync(pagesJsonDir, 'utf-8')));
|
||||
this.routes = this.getPagesRoutes().concat(this.getSubPackagesRoutes());
|
||||
this.tabbar = this.getTabbarRoutes();
|
||||
this.routesMap = this.transformPathToKey(this.routes);
|
||||
}
|
||||
/**
|
||||
* 通过读取pages.json文件 生成直接可用的routes
|
||||
*/
|
||||
getPagesRoutes(pages = this.uniPagesJSON.pages, rootPath = null) {
|
||||
let routes = [];
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const item = pages[i];
|
||||
let route = {};
|
||||
for (let j = 0; j < this.includes.length; j++) {
|
||||
const key = this.includes[j];
|
||||
let value = item[key];
|
||||
if (key === 'path') {
|
||||
value = rootPath ? `/${rootPath}/${value}` : `/${value}`;
|
||||
}
|
||||
if (key === 'aliasPath' && i == 0 && rootPath == null) {
|
||||
route[key] = route[key] || '/';
|
||||
} else if (value !== undefined) {
|
||||
route[key] = value;
|
||||
}
|
||||
}
|
||||
routes.push(route);
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
/**
|
||||
* 解析小程序分包路径
|
||||
*/
|
||||
getSubPackagesRoutes() {
|
||||
if (!(this.uniPagesJSON && this.uniPagesJSON.subPackages)) {
|
||||
return [];
|
||||
}
|
||||
const subPackages = this.uniPagesJSON.subPackages;
|
||||
let routes = [];
|
||||
for (let i = 0; i < subPackages.length; i++) {
|
||||
const subPages = subPackages[i].pages;
|
||||
const root = subPackages[i].root;
|
||||
const subRoutes = this.getPagesRoutes(subPages, root);
|
||||
routes = routes.concat(subRoutes);
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
getTabbarRoutes() {
|
||||
if (!(this.uniPagesJSON && this.uniPagesJSON.tabBar && this.uniPagesJSON.tabBar.list)) {
|
||||
return [];
|
||||
}
|
||||
const tabbar = this.uniPagesJSON.tabBar.list;
|
||||
let tabbarMap = [];
|
||||
tabbar.forEach((bar) => {
|
||||
tabbarMap.push('/' + bar.pagePath);
|
||||
});
|
||||
return tabbarMap;
|
||||
}
|
||||
|
||||
transformPathToKey(list) {
|
||||
if (!isArray(list) || isEmpty(list)) {
|
||||
return [];
|
||||
}
|
||||
let map = {};
|
||||
list.forEach((i) => {
|
||||
map[i.path] = i;
|
||||
});
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
function uniReadPagesV3Plugin({ pagesJsonDir, includes }) {
|
||||
let defaultIncludes = ['path', 'aliasPath', 'name'];
|
||||
includes = [...defaultIncludes, ...includes];
|
||||
let pages = new TransformPages({
|
||||
pagesJsonDir,
|
||||
includes,
|
||||
});
|
||||
return {
|
||||
name: 'uni-read-pages-v3',
|
||||
config(config) {
|
||||
return {
|
||||
define: {
|
||||
ROUTES: pages.routes,
|
||||
ROUTES_MAP: pages.routesMap,
|
||||
TABBAR: pages.tabbar,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
exports.default = uniReadPagesV3Plugin;
|
Reference in New Issue
Block a user