From d94903ba264dd083877e20dd0ca50a1c338b79bc Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Fri, 26 Jul 2019 20:28:38 +0800 Subject: [PATCH] refactor route --- packages/uni-app-plus-nvue/dist/index.js | 241 ++++++++++++++---- .../service/api/route/navigate-back.js | 22 +- .../service/api/route/navigate-to.js | 3 +- .../service/api/route/re-launch.js | 50 +++- .../service/api/route/redirect-to.js | 43 +++- .../service/api/route/switch-tab.js | 75 +++++- .../app-plus-nvue/service/api/route/util.js | 9 +- src/platforms/app-plus/service/api/util.js | 11 +- .../app-plus/service/framework/page.js | 51 ++-- .../app-plus/service/framework/tab-bar.js | 5 +- .../service/framework/webview/index.js | 4 +- .../webview/parser/webview-style-parser.js | 11 +- 12 files changed, 417 insertions(+), 108 deletions(-) diff --git a/packages/uni-app-plus-nvue/dist/index.js b/packages/uni-app-plus-nvue/dist/index.js index c6abb828..2b5288d3 100644 --- a/packages/uni-app-plus-nvue/dist/index.js +++ b/packages/uni-app-plus-nvue/dist/index.js @@ -45,12 +45,12 @@ var serviceContext = (function () { } } - function isTabBarPage (route = '') { + function isTabBarPage (path = '') { if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { return false } try { - if (!route) { + if (!path) { const pages = getCurrentPages(); if (!pages.length) { return false @@ -59,12 +59,9 @@ var serviceContext = (function () { if (!page) { return false } - route = page.route; + return page.$page.meta.isTabBar } - return !!__uniConfig.tabBar.list.find(tabBarPage => { - const pagePath = tabBarPage.pagePath; - return pagePath === route || pagePath === (route + '.html') - }) + return __uniRoutes.find(route => route.path === path).meta.isTabBar } catch (e) { if (process.env.NODE_ENV !== 'production') { console.log('getCurrentPages is not ready'); @@ -464,6 +461,12 @@ var serviceContext = (function () { } } + const ANI_SHOW = 'pop-in'; + const ANI_DURATION = 300; + + const TABBAR_HEIGHT = 56; + const TITLEBAR_HEIGHT = 44; + const WEBVIEW_STYLE_BLACKLIST = [ 'navigationBarBackgroundColor', 'navigationBarTextStyle', @@ -481,7 +484,7 @@ var serviceContext = (function () { 'pullToRefresh' ]; - function parseWebviewStyle (id, path, routeOptions = {}) { + function parseWebviewStyle (id, path, routeOptions = {}) { const webviewStyle = Object.create(null); // 合并 @@ -527,6 +530,11 @@ var serviceContext = (function () { }; } + if (routeOptions.meta.isTabBar) { + webviewStyle.top = 0; + webviewStyle.bottom = TABBAR_HEIGHT; + } + return webviewStyle } @@ -563,8 +571,8 @@ var serviceContext = (function () { ); if (process.env.NODE_ENV !== 'production') { console.log(`[uni-app] updateWebview`, webviewStyle); - } - + } + webview.setStyle(webviewStyle); } @@ -594,27 +602,11 @@ var serviceContext = (function () { const pages = []; - function getCurrentPages$1 () { - return pages + function getCurrentPages$1 (returnAll) { + return returnAll ? pages.slice(0) : pages.filter(page => { + return !page.$page.meta.isTabBar || page.$page.meta.visible + }) } - /** - * @param {Object} pageVm - * - * page.beforeCreate 时添加 page - * page.beforeDestroy 时移出 page - * - * page.viewappear onShow - * page.viewdisappear onHide - * - * navigateTo - * redirectTo - * - * - * - * - * - * - */ /** * 首页需要主动registerPage,二级页面路由跳转时registerPage @@ -622,14 +614,29 @@ var serviceContext = (function () { function registerPage ({ path, query, + openType, webview }) { const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path))); + if (openType === 'reLaunch' || pages.length === 0) { + // pages.length===0 表示首页触发 redirectTo + routeOptions.meta.isQuit = true; + } + if (!webview) { webview = createWebview(path, routeOptions); } + if (routeOptions.meta.isTabBar) { + routeOptions.meta.visible = true; + } + + if (routeOptions.meta.isTabBar && webview.id !== '1') { + const launchWebview = plus.webview.getLaunchWebview(); + launchWebview && launchWebview.append(webview); + } + if (process.env.NODE_ENV !== 'production') { console.log(`[uni-app] registerPage`, path, webview.id); } @@ -650,7 +657,17 @@ var serviceContext = (function () { id: parseInt(webview.id), meta: routeOptions.meta, path, - route + route, + openType + }, + $remove () { + const index = pages.findIndex(page => page === this); + if (index !== -1) { + pages.splice(index, 1); + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] removePage`, path, webview.id); + } + } } }); @@ -710,12 +727,6 @@ var serviceContext = (function () { callbacks[type] = callback; } - const ANI_SHOW = 'pop-in'; - const ANI_DURATION = 300; - - const TABBAR_HEIGHT = 56; - const TITLEBAR_HEIGHT = 44; - var safeArea = { get bottom () { if (plus.os.name === 'iOS') { @@ -1186,7 +1197,10 @@ var serviceContext = (function () { switchTab (page) { if (itemLength) { for (let i = 0; i < itemLength; i++) { - if (config.list[i].pagePath === (`${page}.html`)) { + if ( + config.list[i].pagePath === page || + config.list[i].pagePath === `${page}.html` + ) { const draws = getSelectedDraws(i); if (draws.length) { view.draw(draws); @@ -7297,14 +7311,15 @@ var serviceContext = (function () { const ANI_DURATION$1 = 300; const ANI_SHOW$1 = 'pop-in'; + const ANI_CLOSE = 'pop-out'; - function showWebview (webview, animationType, animationDuration) { + function showWebview (webview, animationType, animationDuration, callback) { setTimeout(() => { webview.show( animationType || ANI_SHOW$1, - animationDuration || ANI_DURATION$1, + parseInt(animationDuration) || ANI_DURATION$1, () => { - console.log('show.callback'); + callback && callback(); } ); }, 50); @@ -7360,16 +7375,19 @@ var serviceContext = (function () { if (animationType) { currentPage.$getAppWebview().close(animationType, animationDuration || ANI_DURATION$1); } else { + if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 + currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION$1); + } currentPage.$getAppWebview().close('auto'); } - // 移除所有 page - pages.splice(len - delta, len); + + pages.slice(len - delta, len).forEach(page => page.$remove()); setStatusBarStyle(); UniServiceJSBridge.emit('onAppRoute', { type: 'navigateBack' - }); + }); }); } @@ -7385,7 +7403,7 @@ var serviceContext = (function () { pages[len - 1].$page.meta.isQuit ? quit() - : back(Math.min(len - 1, delta), animationType, animationDuration); + : back(delta, animationType, animationDuration); } function navigateTo$1 ({ @@ -7406,7 +7424,8 @@ var serviceContext = (function () { showWebview( __registerPage({ path, - query + query, + openType: 'navigate' }), animationType, animationDuration @@ -7415,17 +7434,131 @@ var serviceContext = (function () { setStatusBarStyle(); } - function reLaunch$1 ({ - path - }) {} + function reLaunch$1 ({ + url + }) { + const urls = url.split('?'); + const path = urls[0]; + + const query = parseQuery(urls[1] || ''); + + const pages = getCurrentPages(true).slice(0); + + const routeOptions = __uniRoutes.find(route => route.path === path); + + if (routeOptions.meta.isTabBar) { + tabBar.switchTab(url); + } + + showWebview( + __registerPage({ + path, + query, + openType: 'reLaunch' + }), + 'none', + 0 + ); + + pages.forEach(page => { + page.$remove(); + page.$getAppWebview().close('none'); + }); + + setStatusBarStyle(); + } - function redirectTo$1 ({ - path - }) {} + function redirectTo$1 ({ + url + }) { + const urls = url.split('?'); + const path = urls[0]; + + const query = parseQuery(urls[1] || ''); + + const pages = getCurrentPages(); + const lastPage = pages[pages.length - 1]; + + lastPage && lastPage.$remove(); + + showWebview( + __registerPage({ + path, + query, + openType: 'redirect' + }), + 'none', + 0, + () => { + lastPage && lastPage.$getAppWebview().close('none'); + } + ); + + setStatusBarStyle(); + } function switchTab$1 ({ - path - }) {} + url, + from + }) { + const path = url.split('?')[0]; + + tabBar.switchTab(path.slice(1)); + + const pages = getCurrentPages(); + const len = pages.length; + + if (len >= 1) { // 前一个页面是非 tabBar 页面 + const currentPage = pages[len - 1]; + if (!currentPage.$page.meta.isTabBar) { + pages.reverse().forEach(page => { + if (!page.$page.meta.isTabBar && page !== currentPage) { + page.$remove(); + page.$getAppWebview().close('none'); + } + }); + currentPage.$remove(); + if (currentPage.$page.openType === 'redirect') { + currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION$1); + } else { + currentPage.$getAppWebview().close('auto'); + } + } else { + // TODO 客户端 Bug + currentPage.$getAppWebview().hide('none'); + // 前一个 tabBar 触发 onHide + currentPage.$vm.__call_hook('onHide'); + } + } + + let tabBarPage; + // 查找当前 tabBarPage,且设置 visible + getCurrentPages(true).forEach(page => { + if (('/' + page.route) === path) { + page.$page.meta.visible = true; + tabBarPage = page; + } else { + if (page.$page.meta.isTabBar) { + page.$page.meta.visible = false; + } + } + }); + + if (tabBarPage) { + tabBarPage.$vm.__call_hook('onShow'); + tabBarPage.$getAppWebview().show('none'); + } else { + showWebview( + __registerPage({ + path, + query: {}, + openType: 'switchTab' + }) + ); + } + + setStatusBarStyle(); + } diff --git a/src/platforms/app-plus-nvue/service/api/route/navigate-back.js b/src/platforms/app-plus-nvue/service/api/route/navigate-back.js index 4df1febf..50e1d430 100644 --- a/src/platforms/app-plus-nvue/service/api/route/navigate-back.js +++ b/src/platforms/app-plus-nvue/service/api/route/navigate-back.js @@ -1,4 +1,5 @@ import { + ANI_CLOSE, ANI_DURATION } from './util' @@ -8,7 +9,7 @@ import { let firstBackTime = 0 -function quit() { +function quit () { if (!firstBackTime) { firstBackTime = Date.now() plus.nativeUI.toast('再按一次退出应用') @@ -20,7 +21,7 @@ function quit() { } } -function backWebview(webview, callback) { +function backWebview (webview, callback) { if (!webview.__uniapp_webview) { return callback() } @@ -40,7 +41,7 @@ function backWebview(webview, callback) { }) } -function back(delta, animationType, animationDuration) { +function back (delta, animationType, animationDuration) { const pages = getCurrentPages() const len = pages.length const currentPage = pages[len - 1] @@ -56,10 +57,13 @@ function back(delta, animationType, animationDuration) { if (animationType) { currentPage.$getAppWebview().close(animationType, animationDuration || ANI_DURATION) } else { + if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 + currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION) + } currentPage.$getAppWebview().close('auto') } - // 移除所有 page - pages.splice(len - delta, len) + + pages.slice(len - delta, len).forEach(page => page.$remove()) setStatusBarStyle() @@ -69,7 +73,7 @@ function back(delta, animationType, animationDuration) { }) } -export function navigateBack({ +export function navigateBack ({ delta, animationType, animationDuration @@ -79,7 +83,7 @@ export function navigateBack({ uni.hideToast() // 后退时,关闭 toast,loading - pages[len - 1].$page.meta.isQuit ? - quit() : - back(delta, animationType, animationDuration) + pages[len - 1].$page.meta.isQuit + ? quit() + : back(delta, animationType, animationDuration) } diff --git a/src/platforms/app-plus-nvue/service/api/route/navigate-to.js b/src/platforms/app-plus-nvue/service/api/route/navigate-to.js index 260674ad..2e32edef 100644 --- a/src/platforms/app-plus-nvue/service/api/route/navigate-to.js +++ b/src/platforms/app-plus-nvue/service/api/route/navigate-to.js @@ -28,7 +28,8 @@ export function navigateTo ({ showWebview( __registerPage({ path, - query + query, + openType: 'navigate' }), animationType, animationDuration diff --git a/src/platforms/app-plus-nvue/service/api/route/re-launch.js b/src/platforms/app-plus-nvue/service/api/route/re-launch.js index 92e9e52f..4e05a19a 100644 --- a/src/platforms/app-plus-nvue/service/api/route/re-launch.js +++ b/src/platforms/app-plus-nvue/service/api/route/re-launch.js @@ -1,3 +1,47 @@ -export function reLaunch ({ - path -}) {} +import { + parseQuery +} from 'uni-shared' + +import { + showWebview +} from './util' + +import { + setStatusBarStyle +} from '../../bridge' + +import tabBar from '../../../../app-plus/service/framework/tab-bar' + +export function reLaunch ({ + url +}) { + const urls = url.split('?') + const path = urls[0] + + const query = parseQuery(urls[1] || '') + + const pages = getCurrentPages(true).slice(0) + + const routeOptions = __uniRoutes.find(route => route.path === path) + + if (routeOptions.meta.isTabBar) { + tabBar.switchTab(url) + } + + showWebview( + __registerPage({ + path, + query, + openType: 'reLaunch' + }), + 'none', + 0 + ) + + pages.forEach(page => { + page.$remove() + page.$getAppWebview().close('none') + }) + + setStatusBarStyle() +} diff --git a/src/platforms/app-plus-nvue/service/api/route/redirect-to.js b/src/platforms/app-plus-nvue/service/api/route/redirect-to.js index f3c4499e..6ba7e9ae 100644 --- a/src/platforms/app-plus-nvue/service/api/route/redirect-to.js +++ b/src/platforms/app-plus-nvue/service/api/route/redirect-to.js @@ -1,3 +1,40 @@ -export function redirectTo ({ - path -}) {} +import { + parseQuery +} from 'uni-shared' + +import { + showWebview +} from './util' + +import { + setStatusBarStyle +} from '../../bridge' + +export function redirectTo ({ + url +}) { + const urls = url.split('?') + const path = urls[0] + + const query = parseQuery(urls[1] || '') + + const pages = getCurrentPages() + const lastPage = pages[pages.length - 1] + + lastPage && lastPage.$remove() + + showWebview( + __registerPage({ + path, + query, + openType: 'redirect' + }), + 'none', + 0, + () => { + lastPage && lastPage.$getAppWebview().close('none') + } + ) + + setStatusBarStyle() +} diff --git a/src/platforms/app-plus-nvue/service/api/route/switch-tab.js b/src/platforms/app-plus-nvue/service/api/route/switch-tab.js index 1d821325..b42b77aa 100644 --- a/src/platforms/app-plus-nvue/service/api/route/switch-tab.js +++ b/src/platforms/app-plus-nvue/service/api/route/switch-tab.js @@ -1,3 +1,74 @@ +import { + ANI_CLOSE, + ANI_DURATION, + showWebview +} from './util' + +import { + setStatusBarStyle +} from '../../bridge' + +import tabBar from '../../../../app-plus/service/framework/tab-bar' + export function switchTab ({ - path -}) {} + url, + from +}) { + const path = url.split('?')[0] + + tabBar.switchTab(path.slice(1)) + + const pages = getCurrentPages() + const len = pages.length + + if (len >= 1) { // 前一个页面是非 tabBar 页面 + const currentPage = pages[len - 1] + if (!currentPage.$page.meta.isTabBar) { + pages.reverse().forEach(page => { + if (!page.$page.meta.isTabBar && page !== currentPage) { + page.$remove() + page.$getAppWebview().close('none') + } + }) + currentPage.$remove() + if (currentPage.$page.openType === 'redirect') { + currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION) + } else { + currentPage.$getAppWebview().close('auto') + } + } else { + // TODO 客户端 Bug + currentPage.$getAppWebview().hide('none') + // 前一个 tabBar 触发 onHide + currentPage.$vm.__call_hook('onHide') + } + } + + let tabBarPage + // 查找当前 tabBarPage,且设置 visible + getCurrentPages(true).forEach(page => { + if (('/' + page.route) === path) { + page.$page.meta.visible = true + tabBarPage = page + } else { + if (page.$page.meta.isTabBar) { + page.$page.meta.visible = false + } + } + }) + + if (tabBarPage) { + tabBarPage.$vm.__call_hook('onShow') + tabBarPage.$getAppWebview().show('none') + } else { + showWebview( + __registerPage({ + path, + query: {}, + openType: 'switchTab' + }) + ) + } + + setStatusBarStyle() +} diff --git a/src/platforms/app-plus-nvue/service/api/route/util.js b/src/platforms/app-plus-nvue/service/api/route/util.js index 99226886..0077bd7c 100644 --- a/src/platforms/app-plus-nvue/service/api/route/util.js +++ b/src/platforms/app-plus-nvue/service/api/route/util.js @@ -1,14 +1,15 @@ export const ANI_DURATION = 300 const ANI_SHOW = 'pop-in' +export const ANI_CLOSE = 'pop-out' -export function showWebview (webview, animationType, animationDuration) { +export function showWebview (webview, animationType, animationDuration, callback) { setTimeout(() => { webview.show( animationType || ANI_SHOW, - animationDuration || ANI_DURATION, + parseInt(animationDuration) || ANI_DURATION, () => { - console.log('show.callback') + callback && callback() } ) }, 50) -} +} diff --git a/src/platforms/app-plus/service/api/util.js b/src/platforms/app-plus/service/api/util.js index 71be4f18..2ee4b79f 100644 --- a/src/platforms/app-plus/service/api/util.js +++ b/src/platforms/app-plus/service/api/util.js @@ -19,12 +19,12 @@ export function getLastWebview () { } } -export function isTabBarPage (route = '') { +export function isTabBarPage (path = '') { if (!(__uniConfig.tabBar && Array.isArray(__uniConfig.tabBar.list))) { return false } try { - if (!route) { + if (!path) { const pages = getCurrentPages() if (!pages.length) { return false @@ -33,12 +33,9 @@ export function isTabBarPage (route = '') { if (!page) { return false } - route = page.route + return page.$page.meta.isTabBar } - return !!__uniConfig.tabBar.list.find(tabBarPage => { - const pagePath = tabBarPage.pagePath - return pagePath === route || pagePath === (route + '.html') - }) + return __uniRoutes.find(route => route.path === path).meta.isTabBar } catch (e) { if (process.env.NODE_ENV !== 'production') { console.log('getCurrentPages is not ready') diff --git a/src/platforms/app-plus/service/framework/page.js b/src/platforms/app-plus/service/framework/page.js index 380d52a2..e168daa3 100644 --- a/src/platforms/app-plus/service/framework/page.js +++ b/src/platforms/app-plus/service/framework/page.js @@ -5,27 +5,11 @@ import { const pages = [] -export function getCurrentPages () { - return pages +export function getCurrentPages (returnAll) { + return returnAll ? pages.slice(0) : pages.filter(page => { + return !page.$page.meta.isTabBar || page.$page.meta.visible + }) } -/** - * @param {Object} pageVm - * - * page.beforeCreate 时添加 page - * page.beforeDestroy 时移出 page - * - * page.viewappear onShow - * page.viewdisappear onHide - * - * navigateTo - * redirectTo - * - * - * - * - * - * - */ /** * 首页需要主动registerPage,二级页面路由跳转时registerPage @@ -33,14 +17,29 @@ export function getCurrentPages () { export function registerPage ({ path, query, + openType, webview }) { const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path))) + if (openType === 'reLaunch' || pages.length === 0) { + // pages.length===0 表示首页触发 redirectTo + routeOptions.meta.isQuit = true + } + if (!webview) { webview = createWebview(path, routeOptions) } + if (routeOptions.meta.isTabBar) { + routeOptions.meta.visible = true + } + + if (routeOptions.meta.isTabBar && webview.id !== '1') { + const launchWebview = plus.webview.getLaunchWebview() + launchWebview && launchWebview.append(webview) + } + if (process.env.NODE_ENV !== 'production') { console.log(`[uni-app] registerPage`, path, webview.id) } @@ -61,7 +60,17 @@ export function registerPage ({ id: parseInt(webview.id), meta: routeOptions.meta, path, - route + route, + openType + }, + $remove () { + const index = pages.findIndex(page => page === this) + if (index !== -1) { + pages.splice(index, 1) + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] removePage`, path, webview.id) + } + } } }) diff --git a/src/platforms/app-plus/service/framework/tab-bar.js b/src/platforms/app-plus/service/framework/tab-bar.js index 1f337470..96053359 100644 --- a/src/platforms/app-plus/service/framework/tab-bar.js +++ b/src/platforms/app-plus/service/framework/tab-bar.js @@ -469,7 +469,10 @@ export default { switchTab (page) { if (itemLength) { for (let i = 0; i < itemLength; i++) { - if (config.list[i].pagePath === (`${page}.html`)) { + if ( + config.list[i].pagePath === page || + config.list[i].pagePath === `${page}.html` + ) { const draws = getSelectedDraws(i) if (draws.length) { view.draw(draws) diff --git a/src/platforms/app-plus/service/framework/webview/index.js b/src/platforms/app-plus/service/framework/webview/index.js index c20c9ea2..4d0046fa 100644 --- a/src/platforms/app-plus/service/framework/webview/index.js +++ b/src/platforms/app-plus/service/framework/webview/index.js @@ -40,8 +40,8 @@ export function initWebview (webview, routeOptions) { ) if (process.env.NODE_ENV !== 'production') { console.log(`[uni-app] updateWebview`, webviewStyle) - } - + } + webview.setStyle(webviewStyle) } diff --git a/src/platforms/app-plus/service/framework/webview/parser/webview-style-parser.js b/src/platforms/app-plus/service/framework/webview/parser/webview-style-parser.js index d53c88f6..bc1ea8af 100644 --- a/src/platforms/app-plus/service/framework/webview/parser/webview-style-parser.js +++ b/src/platforms/app-plus/service/framework/webview/parser/webview-style-parser.js @@ -6,6 +6,10 @@ import { parsePullToRefresh } from './pull-to-refresh-parser' +import { + TABBAR_HEIGHT +} from '../../../constants' + const WEBVIEW_STYLE_BLACKLIST = [ 'navigationBarBackgroundColor', 'navigationBarTextStyle', @@ -23,7 +27,7 @@ const WEBVIEW_STYLE_BLACKLIST = [ 'pullToRefresh' ] -export function parseWebviewStyle (id, path, routeOptions = {}) { +export function parseWebviewStyle (id, path, routeOptions = {}) { const webviewStyle = Object.create(null) // 合并 @@ -69,5 +73,10 @@ export function parseWebviewStyle (id, path, routeOptions = {}) { } } + if (routeOptions.meta.isTabBar) { + webviewStyle.top = 0 + webviewStyle.bottom = TABBAR_HEIGHT + } + return webviewStyle } -- GitLab