提交 0452b21f 编写于 作者: fxy060608's avatar fxy060608

feat(v3): unPreloadPage

上级 bd7e5c62
...@@ -207,6 +207,7 @@ const third = [ ...@@ -207,6 +207,7 @@ const third = [
'onNativeEventReceive', 'onNativeEventReceive',
'sendNativeEvent', 'sendNativeEvent',
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
] ]
......
...@@ -218,6 +218,7 @@ var serviceContext = (function () { ...@@ -218,6 +218,7 @@ var serviceContext = (function () {
'onNativeEventReceive', 'onNativeEventReceive',
'sendNativeEvent', 'sendNativeEvent',
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
]; ];
...@@ -1725,8 +1726,9 @@ var serviceContext = (function () { ...@@ -1725,8 +1726,9 @@ var serviceContext = (function () {
// 参数格式化 // 参数格式化
params.url = encodeQueryString(url); params.url = encodeQueryString(url);
if (type === 'unPreloadPage') {
if (type === 'preloadPage') { return
} else if (type === 'preloadPage') {
{ {
if (!routeOptions.meta.isNVue) { if (!routeOptions.meta.isNVue) {
return 'can not preload vue page' return 'can not preload vue page'
...@@ -1834,6 +1836,14 @@ var serviceContext = (function () { ...@@ -1834,6 +1836,14 @@ var serviceContext = (function () {
required: true, required: true,
validator: createValidator('preloadPage') validator: createValidator('preloadPage')
} }
};
const unPreloadPage = {
url: {
type: String,
required: true,
validator: createValidator('unPreloadPage')
}
}; };
var require_context_module_0_24 = /*#__PURE__*/Object.freeze({ var require_context_module_0_24 = /*#__PURE__*/Object.freeze({
...@@ -1843,7 +1853,8 @@ var serviceContext = (function () { ...@@ -1843,7 +1853,8 @@ var serviceContext = (function () {
navigateTo: navigateTo, navigateTo: navigateTo,
switchTab: switchTab, switchTab: switchTab,
navigateBack: navigateBack, navigateBack: navigateBack,
preloadPage: preloadPage preloadPage: preloadPage,
unPreloadPage: unPreloadPage
}); });
const getStorage = { const getStorage = {
...@@ -7530,116 +7541,6 @@ var serviceContext = (function () { ...@@ -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) { function createButtonOnClick (index) {
return function onClick (btn) { return function onClick (btn) {
const pages = getCurrentPages(); const pages = getCurrentPages();
...@@ -8338,6 +8239,10 @@ var serviceContext = (function () { ...@@ -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) { function showWebview (webview, animationType, animationDuration, showCallback, delay) {
if (typeof delay === 'undefined') { if (typeof delay === 'undefined') {
delay = webview.nvue ? 0 : 100; delay = webview.nvue ? 0 : 100;
...@@ -8387,6 +8292,117 @@ var serviceContext = (function () { ...@@ -8387,6 +8292,117 @@ var serviceContext = (function () {
}, delay); }, 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); const pageFactory = Object.create(null);
function definePage (name, createPageVueComponent) { function definePage (name, createPageVueComponent) {
...@@ -8421,7 +8437,7 @@ var serviceContext = (function () { ...@@ -8421,7 +8437,7 @@ var serviceContext = (function () {
* 指定路由 ready 后,检查是否触发分包预加载 * 指定路由 ready 后,检查是否触发分包预加载
* @param {Object} route * @param {Object} route
*/ */
function preloadSubPackages(route) { function preloadSubPackages (route) {
if (!__uniConfig.preloadRule) { if (!__uniConfig.preloadRule) {
return return
} }
...@@ -8436,7 +8452,7 @@ var serviceContext = (function () { ...@@ -8436,7 +8452,7 @@ var serviceContext = (function () {
const network = options.network || 'wifi'; const network = options.network || 'wifi';
if (network === 'wifi') { if (network === 'wifi') {
uni.getNetworkType({ uni.getNetworkType({
success(res) { success (res) {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options)); console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options));
} }
...@@ -8453,7 +8469,7 @@ var serviceContext = (function () { ...@@ -8453,7 +8469,7 @@ var serviceContext = (function () {
} }
} }
function loadPage(route, callback) { function loadPage (route, callback) {
let isInSubPackage = false; let isInSubPackage = false;
const subPackages = __uniConfig.subPackages; const subPackages = __uniConfig.subPackages;
if (Array.isArray(subPackages)) { if (Array.isArray(subPackages)) {
...@@ -8468,7 +8484,7 @@ var serviceContext = (function () { ...@@ -8468,7 +8484,7 @@ var serviceContext = (function () {
} }
} }
function loadSubPackage$2(root, callback) { function loadSubPackage$2 (root, callback) {
if (loadedSubPackages.indexOf(root) !== -1) { if (loadedSubPackages.indexOf(root) !== -1) {
return callback() return callback()
} }
...@@ -8477,27 +8493,27 @@ var serviceContext = (function () { ...@@ -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') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages)); console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages));
} }
const startTime = Date.now(); const startTime = Date.now();
Promise.all( evaluateScriptFiles(packages.map(root => {
packages.map(root => { loadedSubPackages.push(root);
// 目前阶段:假定一定会加载成功 return root + '/' + SUB_FILENAME$1
loadedSubPackages.push(root); }), res => {
return uni.loadSubPackage({
root
})
})
).then(res => {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime)); console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime));
} }
callback && callback(true); callback && callback(true);
}).catch(err => {
console.log(err);
callback && callback(false);
}); });
} }
...@@ -8511,6 +8527,36 @@ var serviceContext = (function () { ...@@ -8511,6 +8527,36 @@ var serviceContext = (function () {
const preloadWebviews = {}; 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 ({ function preloadWebview$1 ({
url, url,
path, path,
...@@ -8538,7 +8584,21 @@ var serviceContext = (function () { ...@@ -8538,7 +8584,21 @@ var serviceContext = (function () {
}) { }) {
if (preloadWebviews[url]) { if (preloadWebviews[url]) {
webview = 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))); const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path)));
...@@ -8617,9 +8677,9 @@ var serviceContext = (function () { ...@@ -8617,9 +8677,9 @@ var serviceContext = (function () {
pages.push(pageInstance); pages.push(pageInstance);
// if (webview.__preload__) { if (webview.__preload__) {
// // TODO 触发 onShow 以及绑定vm,page 关系 webview.__page__ = pageInstance;
// } }
// 首页是 nvue 时,在 registerPage 时,执行路由堆栈 // 首页是 nvue 时,在 registerPage 时,执行路由堆栈
if (webview.id === '1' && webview.nvue) { if (webview.id === '1' && webview.nvue) {
...@@ -8733,8 +8793,8 @@ var serviceContext = (function () { ...@@ -8733,8 +8793,8 @@ var serviceContext = (function () {
0, 0,
() => { () => {
pages.forEach(page => { pages.forEach(page => {
page.$remove(); page.$remove();
page.$getAppWebview().close('none'); closeWebview(page.$getAppWebview(), 'none');
}); });
invoke$1(callbackId, { invoke$1(callbackId, {
errMsg: 'reLaunch:ok' errMsg: 'reLaunch:ok'
...@@ -8780,7 +8840,13 @@ var serviceContext = (function () { ...@@ -8780,7 +8840,13 @@ var serviceContext = (function () {
'none', 'none',
0, 0,
() => { () => {
lastPage && lastPage.$getAppWebview().close('none'); if (lastPage) {
const webview = lastPage.$getAppWebview();
if (webview.__preload__) {
removePreloadWebview(webview);
}
webview.close('none');
}
invoke$1(callbackId, { invoke$1(callbackId, {
errMsg: 'redirectTo:ok' errMsg: 'redirectTo:ok'
}); });
...@@ -8806,7 +8872,7 @@ var serviceContext = (function () { ...@@ -8806,7 +8872,7 @@ var serviceContext = (function () {
function _switchTab ({ function _switchTab ({
url, url,
path, path,
query, query,
from from
}, callbackId) { }, callbackId) {
...@@ -8830,16 +8896,16 @@ var serviceContext = (function () { ...@@ -8830,16 +8896,16 @@ var serviceContext = (function () {
pages.reverse().forEach(page => { pages.reverse().forEach(page => {
if (!page.$page.meta.isTabBar && page !== currentPage) { if (!page.$page.meta.isTabBar && page !== currentPage) {
page.$remove(); page.$remove();
page.$getAppWebview().close('none'); closeWebview(page.$getAppWebview(), 'none');
} }
}); });
currentPage.$remove(); currentPage.$remove();
// 延迟执行避免iOS应用退出 // 延迟执行避免iOS应用退出
setTimeout(() => { setTimeout(() => {
if (currentPage.$page.openType === 'redirect') { if (currentPage.$page.openType === 'redirect') {
currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION); closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION);
} else { } else {
currentPage.$getAppWebview().close('auto'); closeWebview(currentPage.$getAppWebview(), 'auto');
} }
}, 100); }, 100);
} else { } else {
...@@ -8870,9 +8936,12 @@ var serviceContext = (function () { ...@@ -8870,9 +8936,12 @@ var serviceContext = (function () {
currentPage.$vm.__call_hook('onHide'); currentPage.$vm.__call_hook('onHide');
} }
if (tabBarPage) { if (tabBarPage) {
tabBarPage.$getAppWebview().show('none'); const webview = tabBarPage.$getAppWebview();
webview.show('none');
// 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确
callOnShow && tabBarPage.$vm.__call_hook('onShow'); if (callOnShow && !webview.__preload__) {
tabBarPage.$vm.__call_hook('onShow');
}
} else { } else {
return showWebview(registerPage({ return showWebview(registerPage({
url, url,
...@@ -8905,13 +8974,32 @@ var serviceContext = (function () { ...@@ -8905,13 +8974,32 @@ var serviceContext = (function () {
navigate(path, function () { navigate(path, function () {
_switchTab({ _switchTab({
url, url,
path, path,
query, query,
from from
}, callbackId); }, callbackId);
}, openType === 'appLaunch'); }, 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 ({ function preloadPage$1 ({
url url
}, callbackId) { }, callbackId) {
...@@ -9853,6 +9941,7 @@ var serviceContext = (function () { ...@@ -9853,6 +9941,7 @@ var serviceContext = (function () {
reLaunch: reLaunch$1, reLaunch: reLaunch$1,
redirectTo: redirectTo$1, redirectTo: redirectTo$1,
switchTab: switchTab$1, switchTab: switchTab$1,
unPreloadPage: unPreloadPage$1,
preloadPage: preloadPage$1, preloadPage: preloadPage$1,
setStorage: setStorage$1, setStorage: setStorage$1,
setStorageSync: setStorageSync$1, setStorageSync: setStorageSync$1,
......
...@@ -76,8 +76,9 @@ function createValidator (type) { ...@@ -76,8 +76,9 @@ function createValidator (type) {
// 参数格式化 // 参数格式化
params.url = encodeQueryString(url) params.url = encodeQueryString(url)
if (type === 'unPreloadPage') {
if (type === 'preloadPage') { return
} else if (type === 'preloadPage') {
if (__PLATFORM__ === 'app-plus') { if (__PLATFORM__ === 'app-plus') {
if (!routeOptions.meta.isNVue) { if (!routeOptions.meta.isNVue) {
return 'can not preload vue page' return 'can not preload vue page'
...@@ -185,4 +186,12 @@ export const preloadPage = { ...@@ -185,4 +186,12 @@ export const preloadPage = {
required: true, required: true,
validator: createValidator('preloadPage') validator: createValidator('preloadPage')
} }
} }
export const unPreloadPage = {
url: {
type: String,
required: true,
validator: createValidator('unPreloadPage')
}
}
...@@ -7,6 +7,10 @@ import { ...@@ -7,6 +7,10 @@ import {
setStatusBarStyle setStatusBarStyle
} from '../../bridge' } from '../../bridge'
import {
closeWebview
} from './util'
let firstBackTime = 0 let firstBackTime = 0
function quit () { function quit () {
...@@ -46,18 +50,19 @@ function back (delta, animationType, animationDuration) { ...@@ -46,18 +50,19 @@ function back (delta, animationType, animationDuration) {
if (delta > 1) { if (delta > 1) {
// 中间页隐藏 // 中间页隐藏
pages.slice(len - delta, len - 1).reverse().forEach(deltaPage => { pages.slice(len - delta, len - 1).reverse().forEach(deltaPage => {
deltaPage.$getAppWebview().close('none') closeWebview(deltaPage.$getAppWebview(), 'none')
}) })
} }
const backPage = function (webview) { const backPage = function (webview) {
if (animationType) { if (animationType) {
webview.close(animationType, animationDuration || ANI_DURATION) closeWebview(webview, animationType, animationDuration || ANI_DURATION)
} else { } else {
if (currentPage.$page.openType === 'redirect') { // 如果是 redirectTo 跳转的,需要制定 back 动画 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()) pages.slice(len - delta, len).forEach(page => page.$remove())
......
...@@ -7,9 +7,29 @@ import { ...@@ -7,9 +7,29 @@ import {
} from '../../bridge' } from '../../bridge'
import { import {
preloadWebview preloadWebview,
closePreloadWebview
} from '../../framework/page' } 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 ({ export function preloadPage ({
url url
}, callbackId) { }, callbackId) {
...@@ -26,4 +46,4 @@ export function preloadPage ({ ...@@ -26,4 +46,4 @@ export function preloadPage ({
url, url,
errMsg: 'preloadPage:ok' errMsg: 'preloadPage:ok'
}) })
} }
...@@ -3,7 +3,8 @@ import { ...@@ -3,7 +3,8 @@ import {
} from 'uni-shared' } from 'uni-shared'
import { import {
showWebview showWebview,
closeWebview
} from './util' } from './util'
import { import {
...@@ -45,8 +46,8 @@ function _reLaunch ({ ...@@ -45,8 +46,8 @@ function _reLaunch ({
0, 0,
() => { () => {
pages.forEach(page => { pages.forEach(page => {
page.$remove() page.$remove()
page.$getAppWebview().close('none') closeWebview(page.$getAppWebview(), 'none')
}) })
invoke(callbackId, { invoke(callbackId, {
errMsg: 'reLaunch:ok' errMsg: 'reLaunch:ok'
......
...@@ -12,7 +12,8 @@ import { ...@@ -12,7 +12,8 @@ import {
} from '../../bridge' } from '../../bridge'
import { import {
registerPage registerPage,
removePreloadWebview
} from '../../framework/page' } from '../../framework/page'
import { import {
...@@ -39,7 +40,13 @@ function _redirectTo ({ ...@@ -39,7 +40,13 @@ function _redirectTo ({
'none', 'none',
0, 0,
() => { () => {
lastPage && lastPage.$getAppWebview().close('none') if (lastPage) {
const webview = lastPage.$getAppWebview()
if (webview.__preload__) {
removePreloadWebview(webview)
}
webview.close('none')
}
invoke(callbackId, { invoke(callbackId, {
errMsg: 'redirectTo:ok' errMsg: 'redirectTo:ok'
}) })
......
import { import {
parseQuery parseQuery
} from 'uni-shared' } from 'uni-shared'
import { import {
ANI_CLOSE, ANI_CLOSE,
ANI_DURATION ANI_DURATION
} from '../../constants' } from '../../constants'
import { import {
showWebview showWebview,
closeWebview
} from './util' } from './util'
import { import {
...@@ -28,7 +29,7 @@ import tabBar from '../../framework/tab-bar' ...@@ -28,7 +29,7 @@ import tabBar from '../../framework/tab-bar'
function _switchTab ({ function _switchTab ({
url, url,
path, path,
query, query,
from from
}, callbackId) { }, callbackId) {
...@@ -52,16 +53,16 @@ function _switchTab ({ ...@@ -52,16 +53,16 @@ function _switchTab ({
pages.reverse().forEach(page => { pages.reverse().forEach(page => {
if (!page.$page.meta.isTabBar && page !== currentPage) { if (!page.$page.meta.isTabBar && page !== currentPage) {
page.$remove() page.$remove()
page.$getAppWebview().close('none') closeWebview(page.$getAppWebview(), 'none')
} }
}) })
currentPage.$remove() currentPage.$remove()
// 延迟执行避免iOS应用退出 // 延迟执行避免iOS应用退出
setTimeout(() => { setTimeout(() => {
if (currentPage.$page.openType === 'redirect') { if (currentPage.$page.openType === 'redirect') {
currentPage.$getAppWebview().close(ANI_CLOSE, ANI_DURATION) closeWebview(currentPage.$getAppWebview(), ANI_CLOSE, ANI_DURATION)
} else { } else {
currentPage.$getAppWebview().close('auto') closeWebview(currentPage.$getAppWebview(), 'auto')
} }
}, 100) }, 100)
} else { } else {
...@@ -92,9 +93,12 @@ function _switchTab ({ ...@@ -92,9 +93,12 @@ function _switchTab ({
currentPage.$vm.__call_hook('onHide') currentPage.$vm.__call_hook('onHide')
} }
if (tabBarPage) { if (tabBarPage) {
tabBarPage.$getAppWebview().show('none') const webview = tabBarPage.$getAppWebview()
webview.show('none')
// 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确 // 等visible状态都切换完之后,再触发onShow,否则开发者在onShow里边 getCurrentPages 会不准确
callOnShow && tabBarPage.$vm.__call_hook('onShow') if (callOnShow && !webview.__preload__) {
tabBarPage.$vm.__call_hook('onShow')
}
} else { } else {
return showWebview(registerPage({ return showWebview(registerPage({
url, url,
...@@ -127,7 +131,7 @@ export function switchTab ({ ...@@ -127,7 +131,7 @@ export function switchTab ({
navigate(path, function () { navigate(path, function () {
_switchTab({ _switchTab({
url, url,
path, path,
query, query,
from from
}, callbackId) }, callbackId)
......
...@@ -7,6 +7,10 @@ import { ...@@ -7,6 +7,10 @@ import {
navigateFinish navigateFinish
} from '../../framework/navigator' } from '../../framework/navigator'
export function closeWebview (webview, animationType, animationDuration) {
webview[webview.__preload__ ? 'hide' : 'close'](animationType, animationDuration)
}
export function showWebview (webview, animationType, animationDuration, showCallback, delay) { export function showWebview (webview, animationType, animationDuration, showCallback, delay) {
if (typeof delay === 'undefined') { if (typeof delay === 'undefined') {
delay = webview.nvue ? 0 : 100 delay = webview.nvue ? 0 : 100
......
...@@ -4,7 +4,7 @@ const loadedSubPackages = [] ...@@ -4,7 +4,7 @@ const loadedSubPackages = []
* 指定路由 ready 后,检查是否触发分包预加载 * 指定路由 ready 后,检查是否触发分包预加载
* @param {Object} route * @param {Object} route
*/ */
export function preloadSubPackages(route) { export function preloadSubPackages (route) {
if (!__uniConfig.preloadRule) { if (!__uniConfig.preloadRule) {
return return
} }
...@@ -19,7 +19,7 @@ export function preloadSubPackages(route) { ...@@ -19,7 +19,7 @@ export function preloadSubPackages(route) {
const network = options.network || 'wifi' const network = options.network || 'wifi'
if (network === 'wifi') { if (network === 'wifi') {
uni.getNetworkType({ uni.getNetworkType({
success(res) { success (res) {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options)) console.log('UNIAPP[preloadRule]:' + res.networkType + ':' + JSON.stringify(options))
} }
...@@ -36,7 +36,7 @@ export function preloadSubPackages(route) { ...@@ -36,7 +36,7 @@ export function preloadSubPackages(route) {
} }
} }
export function loadPage(route, callback) { export function loadPage (route, callback) {
let isInSubPackage = false let isInSubPackage = false
const subPackages = __uniConfig.subPackages const subPackages = __uniConfig.subPackages
if (Array.isArray(subPackages)) { if (Array.isArray(subPackages)) {
...@@ -51,7 +51,7 @@ export function loadPage(route, callback) { ...@@ -51,7 +51,7 @@ export function loadPage(route, callback) {
} }
} }
function loadSubPackage(root, callback) { function loadSubPackage (root, callback) {
if (loadedSubPackages.indexOf(root) !== -1) { if (loadedSubPackages.indexOf(root) !== -1) {
return callback() return callback()
} }
...@@ -60,26 +60,26 @@ function loadSubPackage(root, 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') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages)) console.log('UNIAPP[loadSubPackages]:' + JSON.stringify(packages))
} }
const startTime = Date.now() const startTime = Date.now()
Promise.all( evaluateScriptFiles(packages.map(root => {
packages.map(root => { loadedSubPackages.push(root)
// 目前阶段:假定一定会加载成功 return root + '/' + SUB_FILENAME
loadedSubPackages.push(root) }), res => {
return uni.loadSubPackage({
root
})
})
).then(res => {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime)) console.log('UNIAPP[loadSubPackages]:' + (Date.now() - startTime))
} }
callback && callback(true) callback && callback(true)
}).catch(err => {
console.log(err)
callback && callback(false)
}) })
} }
...@@ -27,6 +27,36 @@ export function getCurrentPages (returnAll) { ...@@ -27,6 +27,36 @@ export function getCurrentPages (returnAll) {
const preloadWebviews = {} 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 ({ export function preloadWebview ({
url, url,
path, path,
...@@ -54,7 +84,21 @@ export function registerPage ({ ...@@ -54,7 +84,21 @@ export function registerPage ({
}) { }) {
if (preloadWebviews[url]) { if (preloadWebviews[url]) {
webview = 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))) const routeOptions = JSON.parse(JSON.stringify(__uniRoutes.find(route => route.path === path)))
...@@ -133,9 +177,9 @@ export function registerPage ({ ...@@ -133,9 +177,9 @@ export function registerPage ({
pages.push(pageInstance) pages.push(pageInstance)
// if (webview.__preload__) { if (webview.__preload__) {
// // TODO 触发 onShow 以及绑定vm,page 关系 webview.__page__ = pageInstance
// } }
// 首页是 nvue 时,在 registerPage 时,执行路由堆栈 // 首页是 nvue 时,在 registerPage 时,执行路由堆栈
if (webview.id === '1' && webview.nvue) { if (webview.id === '1' && webview.nvue) {
......
...@@ -2,8 +2,9 @@ import { ...@@ -2,8 +2,9 @@ import {
isPlainObject isPlainObject
} from 'uni-shared' } from 'uni-shared'
// 不支持的 API 列表 // 不支持的 API 列表
const todos = [ const todos = [
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
// 'getRecorderManager', // 'getRecorderManager',
// 'getBackgroundAudioManager', // 'getBackgroundAudioManager',
......
import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image'
// 不支持的 API 列表 // 不支持的 API 列表
const todos = [ const todos = [
'preloadPage' 'preloadPage',
'unPreloadPage'
// 'hideKeyboard', // 'hideKeyboard',
// 'onGyroscopeChange', // 'onGyroscopeChange',
// 'startGyroscope', // 'startGyroscope',
...@@ -117,4 +118,4 @@ export { ...@@ -117,4 +118,4 @@ export {
protocols, protocols,
todos, todos,
canIUses canIUses
} }
...@@ -2,8 +2,9 @@ import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' ...@@ -2,8 +2,9 @@ import previewImage from '../../../mp-weixin/helpers/normalize-preview-image'
export const protocols = { export const protocols = {
previewImage previewImage
} }
export const todos = [ export const todos = [
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
// 'startBeaconDiscovery', // 'startBeaconDiscovery',
// 'stopBeaconDiscovery', // 'stopBeaconDiscovery',
...@@ -34,10 +35,10 @@ export const todos = [ ...@@ -34,10 +35,10 @@ export const todos = [
// 'chooseInvoiceTitle', // 'chooseInvoiceTitle',
// 'checkIsSupportSoterAuthentication', // 'checkIsSupportSoterAuthentication',
// 'startSoterAuthentication', // 'startSoterAuthentication',
// 'checkIsSoterEnrolledInDevice', // 'checkIsSoterEnrolledInDevice',
// 'vibrate', // 'vibrate',
// 'loadFontFace', // 'loadFontFace',
// 'getExtConfig', // 'getExtConfig',
// 'getExtConfigSync' // 'getExtConfigSync'
] ]
export const canIUses = [ export const canIUses = [
...@@ -53,14 +54,14 @@ export const canIUses = [ ...@@ -53,14 +54,14 @@ export const canIUses = [
'onUserCaptureScreen', 'onUserCaptureScreen',
'vibrateLong', 'vibrateLong',
'vibrateShort', 'vibrateShort',
'createWorker', 'createWorker',
'connectSocket', 'connectSocket',
'onSocketOpen', 'onSocketOpen',
'onSocketError', 'onSocketError',
'sendSocketMessage', 'sendSocketMessage',
'onSocketMessage', 'onSocketMessage',
'closeSocket', 'closeSocket',
'onSocketClose', 'onSocketClose',
'openDocument', 'openDocument',
'updateShareMenu', 'updateShareMenu',
'getShareInfo', 'getShareInfo',
......
import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image'
// 不支持的 API 列表 // 不支持的 API 列表
const todos = [ const todos = [
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
// 'createCameraContext', // 'createCameraContext',
// 'createLivePlayerContext', // 'createLivePlayerContext',
...@@ -60,7 +61,7 @@ const todos = [ ...@@ -60,7 +61,7 @@ const todos = [
// 'setEnableDebug', // 'setEnableDebug',
// 'onWindowResize', // 'onWindowResize',
// 'offWindowResize', // 'offWindowResize',
// 'createOffscreenCanvas', // 'createOffscreenCanvas',
// 'vibrate' // 'vibrate'
] ]
...@@ -154,7 +155,7 @@ const protocols = { ...@@ -154,7 +155,7 @@ const protocols = {
timeout: false timeout: false
} }
}, },
requestPayment: { requestPayment: {
name: tt.pay ? 'pay' : 'requestPayment', name: tt.pay ? 'pay' : 'requestPayment',
args: { args: {
orderInfo: tt.pay ? 'orderInfo' : 'data' orderInfo: tt.pay ? 'orderInfo' : 'data'
...@@ -171,4 +172,4 @@ export { ...@@ -171,4 +172,4 @@ export {
protocols, protocols,
todos, todos,
canIUses canIUses
} }
...@@ -21,8 +21,9 @@ export const protocols = { ...@@ -21,8 +21,9 @@ export const protocols = {
} }
} }
export const todos = [ export const todos = [
'vibrate', 'vibrate',
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
] ]
export const canIUses = [] export const canIUses = []
...@@ -5,6 +5,7 @@ export const protocols = { ...@@ -5,6 +5,7 @@ export const protocols = {
} }
export const todos = [ export const todos = [
'preloadPage', 'preloadPage',
'unPreloadPage',
'loadSubPackage' 'loadSubPackage'
] ]
export const canIUses = [] export const canIUses = []
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册