提交 5fa69b6d 编写于 作者: fxy060608's avatar fxy060608

feat(h5): add backButton

上级 a99e666b
...@@ -38,7 +38,7 @@ declare namespace UniApp { ...@@ -38,7 +38,7 @@ declare namespace UniApp {
interface UniRoute { interface UniRoute {
path: string path: string
redirect?: string alias?: string
meta: PageRouteMeta meta: PageRouteMeta
component?: any component?: any
} }
......
...@@ -133,9 +133,11 @@ function createNormalizeUrl(type: string) { ...@@ -133,9 +133,11 @@ function createNormalizeUrl(type: string) {
url = getRealRoute(url) url = getRealRoute(url)
const pagePath = url.split('?')[0] const pagePath = url.split('?')[0]
// 匹配路由是否存在 // 匹配路由是否存在
const routeOptions = __uniRoutes.find( if (url === '/') {
({ path, redirect }) => path === pagePath || redirect === pagePath // 首页
) url = __uniRoutes[0].path
}
const routeOptions = __uniRoutes.find(({ path }) => path === pagePath)
if (!routeOptions) { if (!routeOptions) {
return 'page `' + url + '` is not found' return 'page `' + url + '` is not found'
......
...@@ -757,32 +757,17 @@ function createRouterOptions() { ...@@ -757,32 +757,17 @@ function createRouterOptions() {
return { return {
history: initHistory(), history: initHistory(),
strict: !!__uniConfig.router.strict, strict: !!__uniConfig.router.strict,
routes: [ routes: __uniRoutes,
{path: __uniRoutes[0].path, redirect: "/"},
...__uniRoutes
],
scrollBehavior scrollBehavior
}; };
} }
function initGuard(router) {
router.beforeEach(beforeEach);
router.afterEach(afterEach);
}
function createAppRouter(router) { function createAppRouter(router) {
initGuard(router);
return router; return router;
} }
function initHistory() { function initHistory() {
const history2 = __UNI_FEATURE_ROUTER_MODE__ === "history" ? createWebHistory() : createWebHashHistory(); const history2 = __UNI_FEATURE_ROUTER_MODE__ === "history" ? createWebHistory() : createWebHashHistory();
return history2; return history2;
} }
const beforeEach = (to, from, next) => {
next();
};
const afterEach = (to, from, failure) => {
console.log("afterEach.id", history.state.__id__);
console.log("afterEach", to, from, failure, JSON.stringify(history.state));
};
var TabBar = /* @__PURE__ */ defineComponent({ var TabBar = /* @__PURE__ */ defineComponent({
name: "TabBar" name: "TabBar"
}); });
...@@ -912,7 +897,7 @@ function initPublicPage(route) { ...@@ -912,7 +897,7 @@ function initPublicPage(route) {
return { return {
id, id,
path: route.path, path: route.path,
route: normalizeRoute(route.meta.route || route.path), route: normalizeRoute(route.path),
fullPath: route.meta.isEntry ? route.meta.pagePath : route.fullPath, fullPath: route.meta.isEntry ? route.meta.pagePath : route.fullPath,
options: {}, options: {},
meta: usePageMeta() meta: usePageMeta()
...@@ -8182,7 +8167,10 @@ function createNormalizeUrl(type) { ...@@ -8182,7 +8167,10 @@ function createNormalizeUrl(type) {
return function normalizeUrl(url, params) { return function normalizeUrl(url, params) {
url = getRealRoute(url); url = getRealRoute(url);
const pagePath = url.split("?")[0]; const pagePath = url.split("?")[0];
const routeOptions = __uniRoutes.find(({path, redirect}) => path === pagePath || redirect === pagePath); if (url === "/") {
url = __uniRoutes[0].path;
}
const routeOptions = __uniRoutes.find(({path}) => path === pagePath);
if (!routeOptions) { if (!routeOptions) {
return "page `" + url + "` is not found"; return "page `" + url + "` is not found";
} }
...@@ -8378,27 +8366,25 @@ const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (options) => { ...@@ -8378,27 +8366,25 @@ const navigateBack = defineAsyncApi(API_NAVIGATE_BACK, (options) => {
} }
getApp().$router.go(-options.delta); getApp().$router.go(-options.delta);
}, NavigateBackProtocol, NavigateBackOptions); }, NavigateBackProtocol, NavigateBackOptions);
const navigateTo = defineAsyncApi(API_NAVIGATE_TO, (options, callback) => { function navigate(type, url, callback) {
const router = getApp().$router; const router = getApp().$router;
router.push({ router[type === "navigateTo" ? "push" : "replace"]({
path: options.url, path: url,
force: true, force: true,
state: createPageState("navigateTo") state: createPageState(type)
}).then((failure) => { }).then((failure) => {
if (isNavigationFailure(failure)) { if (isNavigationFailure(failure)) {
return callback({ return callback({
errMsg: `${API_NAVIGATE_TO}:fail ${failure.message}` errMsg: `:fail ${failure.message}`
}); });
} }
callback(); callback();
}); });
}, NavigateToProtocol, NavigateToOptions); }
const redirectTo = defineAsyncApi(API_REDIRECT_TO, () => { const navigateTo = defineAsyncApi(API_NAVIGATE_TO, (options, callback) => navigate(API_NAVIGATE_TO, options.url, callback), NavigateToProtocol, NavigateToOptions);
}, RedirectToProtocol, RedirectToOptions); const redirectTo = defineAsyncApi(API_REDIRECT_TO, (options, callback) => navigate(API_REDIRECT_TO, options.url, callback), RedirectToProtocol, RedirectToOptions);
const reLaunch = defineAsyncApi(API_RE_LAUNCH, () => { const reLaunch = defineAsyncApi(API_RE_LAUNCH, (options, callback) => navigate(API_RE_LAUNCH, options.url, callback), ReLaunchProtocol, ReLaunchOptions);
}, ReLaunchProtocol, ReLaunchOptions); const switchTab = defineAsyncApi(API_SWITCH_TAB, (options, callback) => navigate(API_SWITCH_TAB, options.url, callback), SwitchTabProtocol, SwitchTabOptions);
const switchTab = defineAsyncApi(API_SWITCH_TAB, () => {
}, SwitchTabProtocol, SwitchTabOptions);
var api = /* @__PURE__ */ Object.freeze({ var api = /* @__PURE__ */ Object.freeze({
__proto__: null, __proto__: null,
[Symbol.toStringTag]: "Module", [Symbol.toStringTag]: "Module",
...@@ -8570,8 +8556,9 @@ var PageHead = /* @__PURE__ */ defineComponent({ ...@@ -8570,8 +8556,9 @@ var PageHead = /* @__PURE__ */ defineComponent({
function createBackButtonTsx(navigationBar) { function createBackButtonTsx(navigationBar) {
if (navigationBar.backButton) { if (navigationBar.backButton) {
return createVNode("div", { return createVNode("div", {
class: "uni-page-head-btn" class: "uni-page-head-btn",
}, [createSvgIconVNode(ICON_PATH_BACK, navigationBar.type === "transparent" ? "#fff" : navigationBar.titleColor, 27)]); onClick: onPageHeadBackButton
}, [createSvgIconVNode(ICON_PATH_BACK, navigationBar.type === "transparent" ? "#fff" : navigationBar.titleColor, 27)], 8, ["onClick"]);
} }
} }
function createButtonsTsx(btns) { function createButtonsTsx(btns) {
...@@ -8667,6 +8654,17 @@ function createPageHeadSearchInputTsx(navigationBar, { ...@@ -8667,6 +8654,17 @@ function createPageHeadSearchInputTsx(navigationBar, {
onInput onInput
}, null, 8, ["focus", "disabled", "style", "placeholder-style", "onFocus", "onBlur", "onInput"])], 4); }, null, 8, ["focus", "disabled", "style", "placeholder-style", "onFocus", "onBlur", "onInput"])], 4);
} }
function onPageHeadBackButton() {
if (getCurrentPages().length === 1) {
uni.reLaunch({
url: "/"
});
} else {
uni.navigateBack({
from: "backbutton"
});
}
}
function usePageHead(navigationBar) { function usePageHead(navigationBar) {
const clazz = computed(() => { const clazz = computed(() => {
const { const {
......
...@@ -45,7 +45,6 @@ export default /*#__PURE__*/ defineComponent({ ...@@ -45,7 +45,6 @@ export default /*#__PURE__*/ defineComponent({
usePageHeadSearchInput(navigationBar)) as PageHeadSearchInput usePageHeadSearchInput(navigationBar)) as PageHeadSearchInput
__UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ && __UNI_FEATURE_NAVIGATIONBAR_TRANSPARENT__ &&
usePageHeadTransparent(headRef, navigationBar) usePageHeadTransparent(headRef, navigationBar)
return () => { return () => {
// 单页面无需back按钮 // 单页面无需back按钮
const backButtonTsx = __UNI_FEATURE_PAGES__ const backButtonTsx = __UNI_FEATURE_PAGES__
...@@ -86,7 +85,7 @@ export default /*#__PURE__*/ defineComponent({ ...@@ -86,7 +85,7 @@ export default /*#__PURE__*/ defineComponent({
function createBackButtonTsx(navigationBar: UniApp.PageNavigationBar) { function createBackButtonTsx(navigationBar: UniApp.PageNavigationBar) {
if (navigationBar.backButton) { if (navigationBar.backButton) {
return ( return (
<div class="uni-page-head-btn"> <div class="uni-page-head-btn" onClick={onPageHeadBackButton}>
{createSvgIconVNode( {createSvgIconVNode(
ICON_PATH_BACK, ICON_PATH_BACK,
navigationBar.type === 'transparent' navigationBar.type === 'transparent'
...@@ -206,6 +205,18 @@ function createPageHeadSearchInputTsx( ...@@ -206,6 +205,18 @@ function createPageHeadSearchInputTsx(
) )
} }
function onPageHeadBackButton() {
if (getCurrentPages().length === 1) {
uni.reLaunch({
url: '/',
})
} else {
;(uni.navigateBack as Function)({
from: 'backbutton',
})
}
}
function usePageHead(navigationBar: UniApp.PageNavigationBar) { function usePageHead(navigationBar: UniApp.PageNavigationBar) {
const clazz = computed(() => { const clazz = computed(() => {
const { type, titlePenetrate, shadowColorType } = navigationBar const { type, titlePenetrate, shadowColorType } = navigationBar
......
...@@ -56,7 +56,7 @@ function initPublicPage(route: RouteLocationNormalizedLoaded) { ...@@ -56,7 +56,7 @@ function initPublicPage(route: RouteLocationNormalizedLoaded) {
return { return {
id, id,
path: route.path, path: route.path,
route: normalizeRoute((route.meta.route as string) || route.path), route: normalizeRoute(route.path),
fullPath: route.meta.isEntry ? route.meta.pagePath : route.fullPath, fullPath: route.meta.isEntry ? route.meta.pagePath : route.fullPath,
options: {}, // $route.query options: {}, // $route.query
meta: usePageMeta(), meta: usePageMeta(),
......
import { App } from 'vue' import { App } from 'vue'
import { import { Router, RouterOptions, RouteRecordRaw } from 'vue-router'
Router,
RouterOptions,
RouteRecordRaw,
NavigationHookAfter,
NavigationGuardWithThis,
} from 'vue-router'
import { import {
createRouter, createRouter,
createWebHistory, createWebHistory,
...@@ -31,21 +25,12 @@ function createRouterOptions(): RouterOptions { ...@@ -31,21 +25,12 @@ function createRouterOptions(): RouterOptions {
return { return {
history: initHistory(), history: initHistory(),
strict: !!__uniConfig.router.strict, strict: !!__uniConfig.router.strict,
routes: [ routes: (__uniRoutes as unknown) as RouteRecordRaw[],
{ path: __uniRoutes[0].path, redirect: '/' },
...__uniRoutes,
] as RouteRecordRaw[],
scrollBehavior, scrollBehavior,
} }
} }
function initGuard(router: Router) {
router.beforeEach(beforeEach)
router.afterEach(afterEach)
}
function createAppRouter(router: Router) { function createAppRouter(router: Router) {
initGuard(router)
return router return router
} }
...@@ -54,22 +39,5 @@ function initHistory() { ...@@ -54,22 +39,5 @@ function initHistory() {
__UNI_FEATURE_ROUTER_MODE__ === 'history' __UNI_FEATURE_ROUTER_MODE__ === 'history'
? createWebHistory() ? createWebHistory()
: createWebHashHistory() : createWebHashHistory()
// history.listen((_to, from, info) => {
// if (info.direction === 'back') {
// const app = getApp()
// const id = history.state.__id__
// if (app && id) {
// ;(app.$refs.app as any).keepAliveExclude = [from + '-' + id]
// }
// }
// })
return history return history
} }
const beforeEach: NavigationGuardWithThis<undefined> = (to, from, next) => {
next()
}
const afterEach: NavigationHookAfter = (to, from, failure) => {
console.log('afterEach.id', history.state.__id__)
console.log('afterEach', to, from, failure, JSON.stringify(history.state))
}
import { isNavigationFailure, Router } from 'vue-router'
import { import {
API_NAVIGATE_TO, API_NAVIGATE_TO,
defineAsyncApi, defineAsyncApi,
NavigateToOptions, NavigateToOptions,
NavigateToProtocol, NavigateToProtocol,
} from '@dcloudio/uni-api' } from '@dcloudio/uni-api'
import { createPageState } from '../../../framework/plugin/page' import { navigate } from './utils'
export const navigateTo = defineAsyncApi<typeof uni.navigateTo>( export const navigateTo = defineAsyncApi<typeof uni.navigateTo>(
API_NAVIGATE_TO, API_NAVIGATE_TO,
(options, callback?: Function) => { (options, callback?: Function) =>
const router = getApp().$router as Router navigate(API_NAVIGATE_TO, options.url, callback!),
router
.push({
path: options.url,
force: true,
state: createPageState('navigateTo'),
})
.then((failure) => {
if (isNavigationFailure(failure)) {
return callback!({
errMsg: `${API_NAVIGATE_TO}:fail ${failure.message}`,
})
}
callback!()
})
},
NavigateToProtocol, NavigateToProtocol,
NavigateToOptions NavigateToOptions
) )
...@@ -4,10 +4,12 @@ import { ...@@ -4,10 +4,12 @@ import {
ReLaunchOptions, ReLaunchOptions,
ReLaunchProtocol, ReLaunchProtocol,
} from '@dcloudio/uni-api' } from '@dcloudio/uni-api'
import { navigate } from './utils'
export const reLaunch = defineAsyncApi( export const reLaunch = defineAsyncApi<typeof uni.reLaunch>(
API_RE_LAUNCH, API_RE_LAUNCH,
() => {}, (options, callback?: Function) =>
navigate(API_RE_LAUNCH, options.url, callback!),
ReLaunchProtocol, ReLaunchProtocol,
ReLaunchOptions ReLaunchOptions
) )
...@@ -4,10 +4,12 @@ import { ...@@ -4,10 +4,12 @@ import {
RedirectToOptions, RedirectToOptions,
RedirectToProtocol, RedirectToProtocol,
} from '@dcloudio/uni-api' } from '@dcloudio/uni-api'
import { navigate } from './utils'
export const redirectTo = defineAsyncApi( export const redirectTo = defineAsyncApi<typeof uni.redirectTo>(
API_REDIRECT_TO, API_REDIRECT_TO,
() => {}, (options, callback?: Function) =>
navigate(API_REDIRECT_TO, options.url, callback!),
RedirectToProtocol, RedirectToProtocol,
RedirectToOptions RedirectToOptions
) )
...@@ -4,10 +4,12 @@ import { ...@@ -4,10 +4,12 @@ import {
SwitchTabOptions, SwitchTabOptions,
SwitchTabProtocol, SwitchTabProtocol,
} from '@dcloudio/uni-api' } from '@dcloudio/uni-api'
import { navigate } from './utils'
export const switchTab = defineAsyncApi( export const switchTab = defineAsyncApi<typeof uni.switchTab>(
API_SWITCH_TAB, API_SWITCH_TAB,
() => {}, (options, callback?: Function) =>
navigate(API_SWITCH_TAB, options.url, callback!),
SwitchTabProtocol, SwitchTabProtocol,
SwitchTabOptions SwitchTabOptions
) )
import { isNavigationFailure, Router } from 'vue-router'
import { createPageState } from '../../../framework/plugin/page'
export function navigate(
type: 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab',
url: string,
callback: Function
) {
const router = getApp().$router as Router
router[type === 'navigateTo' ? 'push' : 'replace']({
path: url,
force: true,
state: createPageState(type),
}).then((failure) => {
if (isNavigationFailure(failure)) {
return callback({
errMsg: `:fail ${failure.message}`,
})
}
callback()
})
}
...@@ -170,8 +170,10 @@ function normalizePagesRoute(pagesJson: UniApp.PagesJson): PageRouteOptions[] { ...@@ -170,8 +170,10 @@ function normalizePagesRoute(pagesJson: UniApp.PagesJson): PageRouteOptions[] {
} }
function generatePageRoute({ name, path, meta }: PageRouteOptions) { function generatePageRoute({ name, path, meta }: PageRouteOptions) {
const { isEntry } = meta
const alias = isEntry ? `\n alias:'/${path}',` : ''
return `{ return `{
path:'/${meta.isEntry ? '' : path}', path:'/${isEntry ? '' : path}',${alias}
component:{ component:{
render() { render() {
return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(${name})]), _: 1 /* STABLE */})) return (openBlock(), createBlock(PageComponent, null, {page: withCtx(() => [createVNode(${name})]), _: 1 /* STABLE */}))
...@@ -187,7 +189,6 @@ function generatePagesRoute(pagesRouteOptions: PageRouteOptions[]) { ...@@ -187,7 +189,6 @@ function generatePagesRoute(pagesRouteOptions: PageRouteOptions[]) {
function generateRoutes(pagesJson: UniApp.PagesJson) { function generateRoutes(pagesJson: UniApp.PagesJson) {
return `window.__uniRoutes=[${[ return `window.__uniRoutes=[${[
`{ path: '/${pagesJson.pages[0].path}', redirect: '/' }`,
...generatePagesRoute(normalizePagesRoute(pagesJson)), ...generatePagesRoute(normalizePagesRoute(pagesJson)),
].join(',')}]` ].join(',')}]`
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册