From 0452b21fbc1cc889fb9f7edc1a81be8b81406a6a Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 9 Jun 2020 15:36:15 +0800 Subject: [PATCH] feat(v3): unPreloadPage --- lib/apis.js | 1 + packages/uni-app-plus/dist/index.v3.js | 377 +++++++++++------- src/core/helpers/protocol/route/route.js | 15 +- .../service/api/route/navigate-back.js | 13 +- .../service/api/route/preload-page.js | 24 +- .../app-plus/service/api/route/re-launch.js | 7 +- .../app-plus/service/api/route/redirect-to.js | 11 +- .../app-plus/service/api/route/switch-tab.js | 24 +- .../app-plus/service/api/route/util.js | 4 + .../service/framework/load-sub-package.js | 34 +- .../app-plus/service/framework/page.js | 52 ++- .../mp-alipay/runtime/api/protocols.js | 5 +- .../mp-baidu/runtime/api/protocols.js | 5 +- src/platforms/mp-qq/runtime/api/protocols.js | 29 +- .../mp-toutiao/runtime/api/protocols.js | 11 +- .../mp-weixin/runtime/api/protocols.js | 5 +- .../quickapp-webview/runtime/api/protocols.js | 3 +- 17 files changed, 405 insertions(+), 215 deletions(-) diff --git a/lib/apis.js b/lib/apis.js index d207ea8d..30fbda2b 100644 --- a/lib/apis.js +++ b/lib/apis.js @@ -207,6 +207,7 @@ const third = [ 'onNativeEventReceive', 'sendNativeEvent', 'preloadPage', + 'unPreloadPage', 'loadSubPackage' ] diff --git a/packages/uni-app-plus/dist/index.v3.js b/packages/uni-app-plus/dist/index.v3.js index 018fe000..97c1e49a 100644 --- a/packages/uni-app-plus/dist/index.v3.js +++ b/packages/uni-app-plus/dist/index.v3.js @@ -218,6 +218,7 @@ var serviceContext = (function () { 'onNativeEventReceive', 'sendNativeEvent', 'preloadPage', + 'unPreloadPage', 'loadSubPackage' ]; @@ -1725,8 +1726,9 @@ var serviceContext = (function () { // 参数格式化 params.url = encodeQueryString(url); - - if (type === 'preloadPage') { + if (type === 'unPreloadPage') { + return + } else if (type === 'preloadPage') { { if (!routeOptions.meta.isNVue) { return 'can not preload vue page' @@ -1834,6 +1836,14 @@ var serviceContext = (function () { required: true, validator: createValidator('preloadPage') } + }; + + const unPreloadPage = { + url: { + type: String, + required: true, + validator: createValidator('unPreloadPage') + } }; var require_context_module_0_24 = /*#__PURE__*/Object.freeze({ @@ -1843,7 +1853,8 @@ var serviceContext = (function () { navigateTo: navigateTo, switchTab: switchTab, navigateBack: navigateBack, - preloadPage: preloadPage + preloadPage: preloadPage, + unPreloadPage: unPreloadPage }); const getStorage = { @@ -7530,116 +7541,6 @@ var serviceContext = (function () { }); } - let firstBackTime = 0; - - function quit () { - if (!firstBackTime) { - firstBackTime = Date.now(); - plus.nativeUI.toast('再按一次退出应用'); - setTimeout(() => { - firstBackTime = null; - }, 2000); - } else if (Date.now() - firstBackTime < 2000) { - plus.runtime.quit(); - } - } - - function backWebview (webview, callback) { - const children = webview.children(); - if (!children || !children.length) { // 有子 webview - return callback() - } - const childWebview = children[0]; - childWebview.canBack(({ - canBack - }) => { - if (canBack) { - childWebview.back(); // webview 返回 - } else { - callback(); - } - }); - } - - function back (delta, animationType, animationDuration) { - const pages = getCurrentPages(); - const len = pages.length; - const currentPage = pages[len - 1]; - - if (delta > 1) { - // 中间页隐藏 - pages.slice(len - delta, len - 1).reverse().forEach(deltaPage => { - deltaPage.$getAppWebview().close('none'); - }); - } - - const backPage = function (webview) { - if (animationType) { - webview.close(animationType, animationDuration || ANI_DURATION); - } else { - if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 - webview.close(ANI_CLOSE, ANI_DURATION); - } - webview.close('auto'); - } - - pages.slice(len - delta, len).forEach(page => page.$remove()); - - setStatusBarStyle(); - - UniServiceJSBridge.emit('onAppRoute', { - type: 'navigateBack' - }); - }; - - const webview = currentPage.$getAppWebview(); - if (!currentPage.__uniapp_webview) { - return backPage(webview) - } - backWebview(webview, () => { - backPage(webview); - }); - } - - function navigateBack$1 ({ - from = 'navigateBack', - delta, - animationType, - animationDuration - }) { - const pages = getCurrentPages(); - - const currentPage = pages[pages.length - 1]; - if ( - currentPage.$vm && - currentPage.$vm.$options.onBackPress && - currentPage.$vm.__call_hook && - currentPage.$vm.__call_hook('onBackPress', { - from - }) - ) { - return - } - - uni.hideToast(); // 后退时,关闭 toast,loading - - if (currentPage.$page.meta.isQuit) { - quit(); - } else if (currentPage.$page.id === 1 && __uniConfig.realEntryPagePath) { - // condition - __uniConfig.entryPagePath = __uniConfig.realEntryPagePath; - delete __uniConfig.realEntryPagePath; - uni.reLaunch({ - url: '/' + __uniConfig.entryPagePath - }); - } else { - back(delta, animationType, animationDuration); - } - return { - errMsg: 'navigateBack:ok' - } - } - function createButtonOnClick (index) { return function onClick (btn) { const pages = getCurrentPages(); @@ -8338,6 +8239,10 @@ var serviceContext = (function () { } } + function closeWebview (webview, animationType, animationDuration) { + webview[webview.__preload__ ? 'hide' : 'close'](animationType, animationDuration); + } + function showWebview (webview, animationType, animationDuration, showCallback, delay) { if (typeof delay === 'undefined') { delay = webview.nvue ? 0 : 100; @@ -8387,6 +8292,117 @@ var serviceContext = (function () { }, delay); } + let firstBackTime = 0; + + function quit () { + if (!firstBackTime) { + firstBackTime = Date.now(); + plus.nativeUI.toast('再按一次退出应用'); + setTimeout(() => { + firstBackTime = null; + }, 2000); + } else if (Date.now() - firstBackTime < 2000) { + plus.runtime.quit(); + } + } + + function backWebview (webview, callback) { + const children = webview.children(); + if (!children || !children.length) { // 有子 webview + return callback() + } + const childWebview = children[0]; + childWebview.canBack(({ + canBack + }) => { + if (canBack) { + childWebview.back(); // webview 返回 + } else { + callback(); + } + }); + } + + function back (delta, animationType, animationDuration) { + const pages = getCurrentPages(); + const len = pages.length; + const currentPage = pages[len - 1]; + + if (delta > 1) { + // 中间页隐藏 + pages.slice(len - delta, len - 1).reverse().forEach(deltaPage => { + closeWebview(deltaPage.$getAppWebview(), 'none'); + }); + } + + const backPage = function (webview) { + if (animationType) { + closeWebview(webview, animationType, animationDuration || ANI_DURATION); + } else { + if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 + closeWebview(webview, ANI_CLOSE, ANI_DURATION); + } else { + closeWebview(webview, 'auto'); + } + } + + pages.slice(len - delta, len).forEach(page => page.$remove()); + + setStatusBarStyle(); + + UniServiceJSBridge.emit('onAppRoute', { + type: 'navigateBack' + }); + }; + + const webview = currentPage.$getAppWebview(); + if (!currentPage.__uniapp_webview) { + return backPage(webview) + } + backWebview(webview, () => { + backPage(webview); + }); + } + + function navigateBack$1 ({ + from = 'navigateBack', + delta, + animationType, + animationDuration + }) { + const pages = getCurrentPages(); + + const currentPage = pages[pages.length - 1]; + if ( + currentPage.$vm && + currentPage.$vm.$options.onBackPress && + currentPage.$vm.__call_hook && + currentPage.$vm.__call_hook('onBackPress', { + from + }) + ) { + return + } + + uni.hideToast(); // 后退时,关闭 toast,loading + + if (currentPage.$page.meta.isQuit) { + quit(); + } else if (currentPage.$page.id === 1 && __uniConfig.realEntryPagePath) { + // condition + __uniConfig.entryPagePath = __uniConfig.realEntryPagePath; + delete __uniConfig.realEntryPagePath; + uni.reLaunch({ + url: '/' + __uniConfig.entryPagePath + }); + } else { + back(delta, animationType, animationDuration); + } + return { + errMsg: 'navigateBack:ok' + } + } + const pageFactory = Object.create(null); function definePage (name, createPageVueComponent) { @@ -8421,7 +8437,7 @@ var serviceContext = (function () { * 指定路由 ready 后,检查是否触发分包预加载 * @param {Object} route */ - function preloadSubPackages(route) { + function preloadSubPackages (route) { if (!__uniConfig.preloadRule) { return } @@ -8436,7 +8452,7 @@ var serviceContext = (function () { const network = options.network || 'wifi'; if (network === 'wifi') { uni.getNetworkType({ - success(res) { + success (res) { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options)); } @@ -8453,7 +8469,7 @@ var serviceContext = (function () { } } - function loadPage(route, callback) { + function loadPage (route, callback) { let isInSubPackage = false; const subPackages = __uniConfig.subPackages; if (Array.isArray(subPackages)) { @@ -8468,7 +8484,7 @@ var serviceContext = (function () { } } - function loadSubPackage$2(root, callback) { + function loadSubPackage$2 (root, callback) { if (loadedSubPackages.indexOf(root) !== -1) { return callback() } @@ -8477,27 +8493,27 @@ var serviceContext = (function () { }); } - function loadSubPackages(packages, callback) { + const SUB_FILENAME$1 = 'app-sub-service.js'; + + function evaluateScriptFiles (files, callback) { + setTimeout(() => { + callback(); + }, 2000); + } + + function loadSubPackages (packages, callback) { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages)); } const startTime = Date.now(); - Promise.all( - packages.map(root => { - // 目前阶段:假定一定会加载成功 - loadedSubPackages.push(root); - return uni.loadSubPackage({ - root - }) - }) - ).then(res => { + evaluateScriptFiles(packages.map(root => { + loadedSubPackages.push(root); + return root + '/' + SUB_FILENAME$1 + }), res => { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime)); } callback && callback(true); - }).catch(err => { - console.log(err); - callback && callback(false); }); } @@ -8511,6 +8527,36 @@ var serviceContext = (function () { const preloadWebviews = {}; + function removePreloadWebview (webview) { + const url = Object.keys(preloadWebviews).find(url => preloadWebviews[url].id === webview.id); + if (url) { + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] removePreloadWebview(${webview.id})`); + } + delete preloadWebviews[url]; + } + } + + function closePreloadWebview ({ + url + }) { + const webview = preloadWebviews[url]; + if (webview) { + if (webview.__page__) { + if (!getCurrentPages$1(true).find(page => page === webview.__page__)) { + // 未使用 + webview.close('none'); + } else { // 被使用 + webview.__preload__ = false; + } + } else { // 未使用 + webview.close('none'); + } + delete preloadWebviews[url]; + } + return webview + } + function preloadWebview$1 ({ url, path, @@ -8538,7 +8584,21 @@ var serviceContext = (function () { }) { if (preloadWebviews[url]) { webview = preloadWebviews[url]; - delete preloadWebviews[url]; + if (webview.__page__) { + // 该预载页面已处于显示状态,不再使用该预加载页面,直接新开 + if (getCurrentPages$1(true).find(page => page === webview.__page__)) { + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] preloadWebview(${path},${webview.id}) already in use`); + } + webview = null; + } else { + pages.push(webview.__page__); + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] reuse preloadWebview(${path},${webview.id})`); + } + return webview + } + } } const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path))); @@ -8617,9 +8677,9 @@ var serviceContext = (function () { pages.push(pageInstance); - // if (webview.__preload__) { - // // TODO 触发 onShow 以及绑定vm,page 关系 - // } + if (webview.__preload__) { + webview.__page__ = pageInstance; + } // 首页是 nvue 时,在 registerPage 时,执行路由堆栈 if (webview.id === '1' && webview.nvue) { @@ -8733,8 +8793,8 @@ var serviceContext = (function () { 0, () => { pages.forEach(page => { - page.$remove(); - page.$getAppWebview().close('none'); + page.$remove(); + closeWebview(page.$getAppWebview(), 'none'); }); invoke$1(callbackId, { errMsg: 'reLaunch:ok' @@ -8780,7 +8840,13 @@ var serviceContext = (function () { 'none', 0, () => { - lastPage && lastPage.$getAppWebview().close('none'); + if (lastPage) { + const webview = lastPage.$getAppWebview(); + if (webview.__preload__) { + removePreloadWebview(webview); + } + webview.close('none'); + } invoke$1(callbackId, { errMsg: 'redirectTo:ok' }); @@ -8806,7 +8872,7 @@ var serviceContext = (function () { function _switchTab ({ url, - path, + path, query, from }, callbackId) { @@ -8830,16 +8896,16 @@ var serviceContext = (function () { pages.reverse().forEach(page => { if (!page.$page.meta.isTabBar && page !== currentPage) { page.$remove(); - page.$getAppWebview().close('none'); + closeWebview(page.$getAppWebview(), 'none'); } }); currentPage.$remove(); // 延迟执行避免iOS应用退出 setTimeout(() => { if (currentPage.$page.openType === 'redirect') { - currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION); + closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION); } else { - currentPage.$getAppWebview().close('auto'); + closeWebview(currentPage.$getAppWebview(), 'auto'); } }, 100); } else { @@ -8870,9 +8936,12 @@ var serviceContext = (function () { currentPage.$vm.__call_hook('onHide'); } if (tabBarPage) { - tabBarPage.$getAppWebview().show('none'); + const webview = tabBarPage.$getAppWebview(); + webview.show('none'); // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 - callOnShow && tabBarPage.$vm.__call_hook('onShow'); + if (callOnShow && !webview.__preload__) { + tabBarPage.$vm.__call_hook('onShow'); + } } else { return showWebview(registerPage({ url, @@ -8905,13 +8974,32 @@ var serviceContext = (function () { navigate(path, function () { _switchTab({ url, - path, + path, query, from }, callbackId); }, openType === 'appLaunch'); } + function unPreloadPage$1 ({ + url + }) { + const webview = closePreloadWebview({ + url + }); + if (webview) { + return { + id: webview.id, + url, + errMsg: 'unPreloadPage:ok' + } + } + return { + url, + errMsg: 'unPreloadPage:fail not found' + } + } + function preloadPage$1 ({ url }, callbackId) { @@ -9853,6 +9941,7 @@ var serviceContext = (function () { reLaunch: reLaunch$1, redirectTo: redirectTo$1, switchTab: switchTab$1, + unPreloadPage: unPreloadPage$1, preloadPage: preloadPage$1, setStorage: setStorage$1, setStorageSync: setStorageSync$1, diff --git a/src/core/helpers/protocol/route/route.js b/src/core/helpers/protocol/route/route.js index 4332bd9d..0b98bbeb 100644 --- a/src/core/helpers/protocol/route/route.js +++ b/src/core/helpers/protocol/route/route.js @@ -76,8 +76,9 @@ function createValidator (type) { // 参数格式化 params.url = encodeQueryString(url) - - if (type === 'preloadPage') { + if (type === 'unPreloadPage') { + return + } else if (type === 'preloadPage') { if (__PLATFORM__ === 'app-plus') { if (!routeOptions.meta.isNVue) { return 'can not preload vue page' @@ -185,4 +186,12 @@ export const preloadPage = { required: true, validator: createValidator('preloadPage') } -} +} + +export const unPreloadPage = { + url: { + type: String, + required: true, + validator: createValidator('unPreloadPage') + } +} diff --git a/src/platforms/app-plus/service/api/route/navigate-back.js b/src/platforms/app-plus/service/api/route/navigate-back.js index 53aed3cb..a2696e7a 100644 --- a/src/platforms/app-plus/service/api/route/navigate-back.js +++ b/src/platforms/app-plus/service/api/route/navigate-back.js @@ -7,6 +7,10 @@ import { setStatusBarStyle } from '../../bridge' +import { + closeWebview +} from './util' + let firstBackTime = 0 function quit () { @@ -46,18 +50,19 @@ function back (delta, animationType, animationDuration) { if (delta > 1) { // 中间页隐藏 pages.slice(len - delta, len - 1).reverse().forEach(deltaPage => { - deltaPage.$getAppWebview().close('none') + closeWebview(deltaPage.$getAppWebview(), 'none') }) } const backPage = function (webview) { if (animationType) { - webview.close(animationType, animationDuration || ANI_DURATION) + closeWebview(webview, animationType, animationDuration || ANI_DURATION) } else { if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 - webview.close(ANI_CLOSE, ANI_DURATION) + closeWebview(webview, ANI_CLOSE, ANI_DURATION) + } else { + closeWebview(webview, 'auto') } - webview.close('auto') } pages.slice(len - delta, len).forEach(page => page.$remove()) diff --git a/src/platforms/app-plus/service/api/route/preload-page.js b/src/platforms/app-plus/service/api/route/preload-page.js index 13a45ff2..65730c34 100644 --- a/src/platforms/app-plus/service/api/route/preload-page.js +++ b/src/platforms/app-plus/service/api/route/preload-page.js @@ -7,9 +7,29 @@ import { } from '../../bridge' import { - preloadWebview + preloadWebview, + closePreloadWebview } from '../../framework/page' +export function unPreloadPage ({ + url +}) { + const webview = closePreloadWebview({ + url + }) + if (webview) { + return { + id: webview.id, + url, + errMsg: 'unPreloadPage:ok' + } + } + return { + url, + errMsg: 'unPreloadPage:fail not found' + } +} + export function preloadPage ({ url }, callbackId) { @@ -26,4 +46,4 @@ export function preloadPage ({ url, errMsg: 'preloadPage:ok' }) -} +} diff --git a/src/platforms/app-plus/service/api/route/re-launch.js b/src/platforms/app-plus/service/api/route/re-launch.js index 7793375f..92b5b5c2 100644 --- a/src/platforms/app-plus/service/api/route/re-launch.js +++ b/src/platforms/app-plus/service/api/route/re-launch.js @@ -3,7 +3,8 @@ import { } from 'uni-shared' import { - showWebview + showWebview, + closeWebview } from './util' import { @@ -45,8 +46,8 @@ function _reLaunch ({ 0, () => { pages.forEach(page => { - page.$remove() - page.$getAppWebview().close('none') + page.$remove() + closeWebview(page.$getAppWebview(), 'none') }) invoke(callbackId, { errMsg: 'reLaunch:ok' diff --git a/src/platforms/app-plus/service/api/route/redirect-to.js b/src/platforms/app-plus/service/api/route/redirect-to.js index ade666e2..b8a025fb 100644 --- a/src/platforms/app-plus/service/api/route/redirect-to.js +++ b/src/platforms/app-plus/service/api/route/redirect-to.js @@ -12,7 +12,8 @@ import { } from '../../bridge' import { - registerPage + registerPage, + removePreloadWebview } from '../../framework/page' import { @@ -39,7 +40,13 @@ function _redirectTo ({ 'none', 0, () => { - lastPage && lastPage.$getAppWebview().close('none') + if (lastPage) { + const webview = lastPage.$getAppWebview() + if (webview.__preload__) { + removePreloadWebview(webview) + } + webview.close('none') + } invoke(callbackId, { errMsg: 'redirectTo:ok' }) diff --git a/src/platforms/app-plus/service/api/route/switch-tab.js b/src/platforms/app-plus/service/api/route/switch-tab.js index 800d2512..366c265b 100644 --- a/src/platforms/app-plus/service/api/route/switch-tab.js +++ b/src/platforms/app-plus/service/api/route/switch-tab.js @@ -1,14 +1,15 @@ import { parseQuery -} from 'uni-shared' - +} from 'uni-shared' + import { ANI_CLOSE, ANI_DURATION } from '../../constants' import { - showWebview + showWebview, + closeWebview } from './util' import { @@ -28,7 +29,7 @@ import tabBar from '../../framework/tab-bar' function _switchTab ({ url, - path, + path, query, from }, callbackId) { @@ -52,16 +53,16 @@ function _switchTab ({ pages.reverse().forEach(page => { if (!page.$page.meta.isTabBar && page !== currentPage) { page.$remove() - page.$getAppWebview().close('none') + closeWebview(page.$getAppWebview(), 'none') } }) currentPage.$remove() // 延迟执行避免iOS应用退出 setTimeout(() => { if (currentPage.$page.openType === 'redirect') { - currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION) + closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION) } else { - currentPage.$getAppWebview().close('auto') + closeWebview(currentPage.$getAppWebview(), 'auto') } }, 100) } else { @@ -92,9 +93,12 @@ function _switchTab ({ currentPage.$vm.__call_hook('onHide') } if (tabBarPage) { - tabBarPage.$getAppWebview().show('none') + const webview = tabBarPage.$getAppWebview() + webview.show('none') // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 - callOnShow && tabBarPage.$vm.__call_hook('onShow') + if (callOnShow && !webview.__preload__) { + tabBarPage.$vm.__call_hook('onShow') + } } else { return showWebview(registerPage({ url, @@ -127,7 +131,7 @@ export function switchTab ({ navigate(path, function () { _switchTab({ url, - path, + path, query, from }, callbackId) diff --git a/src/platforms/app-plus/service/api/route/util.js b/src/platforms/app-plus/service/api/route/util.js index c02644eb..4a8571e6 100644 --- a/src/platforms/app-plus/service/api/route/util.js +++ b/src/platforms/app-plus/service/api/route/util.js @@ -7,6 +7,10 @@ import { navigateFinish } from '../../framework/navigator' +export function closeWebview (webview, animationType, animationDuration) { + webview[webview.__preload__ ? 'hide' : 'close'](animationType, animationDuration) +} + export function showWebview (webview, animationType, animationDuration, showCallback, delay) { if (typeof delay === 'undefined') { delay = webview.nvue ? 0 : 100 diff --git a/src/platforms/app-plus/service/framework/load-sub-package.js b/src/platforms/app-plus/service/framework/load-sub-package.js index 70af742f..d5b7f77a 100644 --- a/src/platforms/app-plus/service/framework/load-sub-package.js +++ b/src/platforms/app-plus/service/framework/load-sub-package.js @@ -4,7 +4,7 @@ const loadedSubPackages = [] * 指定路由 ready 后,检查是否触发分包预加载 * @param {Object} route */ -export function preloadSubPackages(route) { +export function preloadSubPackages (route) { if (!__uniConfig.preloadRule) { return } @@ -19,7 +19,7 @@ export function preloadSubPackages(route) { const network = options.network || 'wifi' if (network === 'wifi') { uni.getNetworkType({ - success(res) { + success (res) { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options)) } @@ -36,7 +36,7 @@ export function preloadSubPackages(route) { } } -export function loadPage(route, callback) { +export function loadPage (route, callback) { let isInSubPackage = false const subPackages = __uniConfig.subPackages if (Array.isArray(subPackages)) { @@ -51,7 +51,7 @@ export function loadPage(route, callback) { } } -function loadSubPackage(root, callback) { +function loadSubPackage (root, callback) { if (loadedSubPackages.indexOf(root) !== -1) { return callback() } @@ -60,26 +60,26 @@ function loadSubPackage(root, callback) { }) } -function loadSubPackages(packages, callback) { +const SUB_FILENAME = 'app-sub-service.js' + +function evaluateScriptFiles (files, callback) { + setTimeout(() => { + callback() + }, 2000) +} + +function loadSubPackages (packages, callback) { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages)) } const startTime = Date.now() - Promise.all( - packages.map(root => { - // 目前阶段:假定一定会加载成功 - loadedSubPackages.push(root) - return uni.loadSubPackage({ - root - }) - }) - ).then(res => { + evaluateScriptFiles(packages.map(root => { + loadedSubPackages.push(root) + return root + '/' + SUB_FILENAME + }), res => { if (process.env.NODE_ENV !== 'production') { console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime)) } callback && callback(true) - }).catch(err => { - console.log(err) - callback && callback(false) }) } diff --git a/src/platforms/app-plus/service/framework/page.js b/src/platforms/app-plus/service/framework/page.js index 5af4346e..01b6eccb 100644 --- a/src/platforms/app-plus/service/framework/page.js +++ b/src/platforms/app-plus/service/framework/page.js @@ -27,6 +27,36 @@ export function getCurrentPages (returnAll) { const preloadWebviews = {} +export function removePreloadWebview (webview) { + const url = Object.keys(preloadWebviews).find(url => preloadWebviews[url].id === webview.id) + if (url) { + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] removePreloadWebview(${webview.id})`) + } + delete preloadWebviews[url] + } +} + +export function closePreloadWebview ({ + url +}) { + const webview = preloadWebviews[url] + if (webview) { + if (webview.__page__) { + if (!getCurrentPages(true).find(page => page === webview.__page__)) { + // 未使用 + webview.close('none') + } else { // 被使用 + webview.__preload__ = false + } + } else { // 未使用 + webview.close('none') + } + delete preloadWebviews[url] + } + return webview +} + export function preloadWebview ({ url, path, @@ -54,7 +84,21 @@ export function registerPage ({ }) { if (preloadWebviews[url]) { webview = preloadWebviews[url] - delete preloadWebviews[url] + if (webview.__page__) { + // 该预载页面已处于显示状态,不再使用该预加载页面,直接新开 + if (getCurrentPages(true).find(page => page === webview.__page__)) { + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] preloadWebview(${path},${webview.id}) already in use`) + } + webview = null + } else { + pages.push(webview.__page__) + if (process.env.NODE_ENV !== 'production') { + console.log(`[uni-app] reuse preloadWebview(${path},${webview.id})`) + } + return webview + } + } } const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path))) @@ -133,9 +177,9 @@ export function registerPage ({ pages.push(pageInstance) - // if (webview.__preload__) { - // // TODO 触发 onShow 以及绑定vm,page 关系 - // } + if (webview.__preload__) { + webview.__page__ = pageInstance + } // 首页是 nvue 时,在 registerPage 时,执行路由堆栈 if (webview.id === '1' && webview.nvue) { diff --git a/src/platforms/mp-alipay/runtime/api/protocols.js b/src/platforms/mp-alipay/runtime/api/protocols.js index f0900711..bd588d9e 100644 --- a/src/platforms/mp-alipay/runtime/api/protocols.js +++ b/src/platforms/mp-alipay/runtime/api/protocols.js @@ -2,8 +2,9 @@ import { isPlainObject } from 'uni-shared' // 不支持的 API 列表 -const todos = [ - 'preloadPage', +const todos = [ + 'preloadPage', + 'unPreloadPage', 'loadSubPackage' // 'getRecorderManager', // 'getBackgroundAudioManager', diff --git a/src/platforms/mp-baidu/runtime/api/protocols.js b/src/platforms/mp-baidu/runtime/api/protocols.js index a487b9c0..6da34346 100644 --- a/src/platforms/mp-baidu/runtime/api/protocols.js +++ b/src/platforms/mp-baidu/runtime/api/protocols.js @@ -1,7 +1,8 @@ import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' // 不支持的 API 列表 const todos = [ - 'preloadPage' + 'preloadPage', + 'unPreloadPage' // 'hideKeyboard', // 'onGyroscopeChange', // 'startGyroscope', @@ -117,4 +118,4 @@ export { protocols, todos, canIUses -} +} diff --git a/src/platforms/mp-qq/runtime/api/protocols.js b/src/platforms/mp-qq/runtime/api/protocols.js index d6a2af5f..8e2a36c7 100644 --- a/src/platforms/mp-qq/runtime/api/protocols.js +++ b/src/platforms/mp-qq/runtime/api/protocols.js @@ -2,8 +2,9 @@ import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' export const protocols = { previewImage } -export const todos = [ - 'preloadPage', +export const todos = [ + 'preloadPage', + 'unPreloadPage', 'loadSubPackage' // 'startBeaconDiscovery', // 'stopBeaconDiscovery', @@ -34,10 +35,10 @@ export const todos = [ // 'chooseInvoiceTitle', // 'checkIsSupportSoterAuthentication', // 'startSoterAuthentication', - // 'checkIsSoterEnrolledInDevice', - // 'vibrate', - // 'loadFontFace', - // 'getExtConfig', + // 'checkIsSoterEnrolledInDevice', + // 'vibrate', + // 'loadFontFace', + // 'getExtConfig', // 'getExtConfigSync' ] export const canIUses = [ @@ -53,14 +54,14 @@ export const canIUses = [ 'onUserCaptureScreen', 'vibrateLong', 'vibrateShort', - 'createWorker', - 'connectSocket', - 'onSocketOpen', - 'onSocketError', - 'sendSocketMessage', - 'onSocketMessage', - 'closeSocket', - 'onSocketClose', + 'createWorker', + 'connectSocket', + 'onSocketOpen', + 'onSocketError', + 'sendSocketMessage', + 'onSocketMessage', + 'closeSocket', + 'onSocketClose', 'openDocument', 'updateShareMenu', 'getShareInfo', diff --git a/src/platforms/mp-toutiao/runtime/api/protocols.js b/src/platforms/mp-toutiao/runtime/api/protocols.js index 14f605a8..df48b112 100644 --- a/src/platforms/mp-toutiao/runtime/api/protocols.js +++ b/src/platforms/mp-toutiao/runtime/api/protocols.js @@ -1,8 +1,9 @@ import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' // 不支持的 API 列表 -const todos = [ - 'preloadPage', +const todos = [ + 'preloadPage', + 'unPreloadPage', 'loadSubPackage' // 'createCameraContext', // 'createLivePlayerContext', @@ -60,7 +61,7 @@ const todos = [ // 'setEnableDebug', // 'onWindowResize', // 'offWindowResize', - // 'createOffscreenCanvas', + // 'createOffscreenCanvas', // 'vibrate' ] @@ -154,7 +155,7 @@ const protocols = { timeout: false } }, - requestPayment: { + requestPayment: { name: tt.pay ? 'pay' : 'requestPayment', args: { orderInfo: tt.pay ? 'orderInfo' : 'data' @@ -171,4 +172,4 @@ export { protocols, todos, canIUses -} +} diff --git a/src/platforms/mp-weixin/runtime/api/protocols.js b/src/platforms/mp-weixin/runtime/api/protocols.js index b3716bd0..432556ab 100644 --- a/src/platforms/mp-weixin/runtime/api/protocols.js +++ b/src/platforms/mp-weixin/runtime/api/protocols.js @@ -21,8 +21,9 @@ export const protocols = { } } export const todos = [ - 'vibrate', - 'preloadPage', + 'vibrate', + 'preloadPage', + 'unPreloadPage', 'loadSubPackage' ] export const canIUses = [] diff --git a/src/platforms/quickapp-webview/runtime/api/protocols.js b/src/platforms/quickapp-webview/runtime/api/protocols.js index b8caade3..82de9780 100644 --- a/src/platforms/quickapp-webview/runtime/api/protocols.js +++ b/src/platforms/quickapp-webview/runtime/api/protocols.js @@ -5,6 +5,7 @@ export const protocols = { } export const todos = [ 'preloadPage', + 'unPreloadPage', 'loadSubPackage' ] -export const canIUses = [] +export const canIUses = [] -- GitLab