提交 9550e4b5 编写于 作者: D DCloud_LXH

feat(App): preloadPage、unPreloadPage

上级 daa52d3c
......@@ -66,6 +66,7 @@ export * from './route/navigateTo'
export * from './route/redirectTo'
export * from './route/reLaunch'
export * from './route/switchTab'
export * from './route/preloadPage'
export {
upx2px,
......
import { parseQuery } from '@dcloudio/uni-shared'
import {
API_PRELOAD_PAGE,
API_TYPE_PRELOAD_PAGE,
PreloadPageProtocol,
API_UN_PRELOAD_PAGE,
API_TYPE_UN_PRELOAD_PAGE,
UnPreloadPageProtocol,
defineAsyncApi,
defineSyncApi,
} from '@dcloudio/uni-api'
import {
preloadWebview,
closePreloadWebview,
} from '../../framework/page/preLoad'
export const unPreloadPage = defineSyncApi<API_TYPE_UN_PRELOAD_PAGE>(
API_UN_PRELOAD_PAGE,
({ url }) => {
const webview = closePreloadWebview({
url,
})
if (webview) {
return {
id: webview.id,
url,
errMsg: 'unPreloadPage:ok',
}
}
return {
url,
errMsg: 'unPreloadPage:fail not found',
}
},
UnPreloadPageProtocol
)
export const preloadPage = defineAsyncApi<API_TYPE_PRELOAD_PAGE>(
API_PRELOAD_PAGE,
({ url }, { resolve, reject }) => {
const urls = url.split('?')
const path = urls[0]
const query = parseQuery(urls[1] || '')
const webview = preloadWebview({
url,
path,
query,
})
resolve({
id: webview.id,
url,
errMsg: 'preloadPage:ok',
})
},
PreloadPageProtocol
)
......@@ -13,6 +13,10 @@ import { navigate, RouteOptions } from './utils'
import { showWebview } from './webview'
import { setStatusBarStyle } from '../../statusBar'
import { ComponentPublicInstance } from 'vue'
import {
removePreloadWebview,
PreloadWebviewObject,
} from '../../framework/page/preLoad'
export const redirectTo = defineAsyncApi<API_TYPE_REDIRECT_TO>(
API_REDIRECT_TO,
......@@ -73,10 +77,9 @@ function _redirectTo({
if (lastPage) {
const webview = (lastPage as ComponentPublicInstance)
.$getAppWebview!()
// TODO preload
// if (webview.__preload__) {
// removePreloadWebview(webview)
// }
if ((webview as PreloadWebviewObject).__preload__) {
removePreloadWebview(webview)
}
webview.close('none')
}
resolve(undefined)
......
import { ComponentPublicInstance } from 'vue'
import { createWebview } from '../webview'
export interface PreloadWebviewObject extends PlusWebviewWebviewObject {
__preload__?: boolean
__query__?: string
__page__?: ComponentPublicInstance
}
export const preloadWebviews: Record<string, PreloadWebviewObject> = {}
export function removePreloadWebview(webview: PreloadWebviewObject) {
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 }: { url: string }) {
const webview = preloadWebviews[url]
if (webview) {
if (webview.__page__) {
if (!getCurrentPages().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,
query,
}: {
url: string
path: string
query: Record<string, string>
}) {
if (!preloadWebviews[url]) {
const routeOptions: UniApp.UniRoute = JSON.parse(
JSON.stringify(__uniRoutes.find((route) => route.path === path))
)
preloadWebviews[url] = createWebview({
path,
routeOptions,
query,
webviewStyle: {
__preload__: true,
__query__: JSON.stringify(query),
},
})
}
return preloadWebviews[url]
}
......@@ -6,7 +6,7 @@ import {
ON_REACH_BOTTOM_DISTANCE,
PageNodeOptions,
} from '@dcloudio/uni-shared'
import { initPageInternalInstance } from '@dcloudio/uni-core'
import { initPageInternalInstance, initPageVm } from '@dcloudio/uni-core'
import { initEntry } from '../app/initEntry'
import { initRouteOptions } from './routeOptions'
......@@ -16,6 +16,7 @@ import { getStatusbarHeight } from '../../../helpers/statusBar'
import tabBar from '../app/tabBar'
import { addCurrentPage } from './getCurrentPages'
import { getBaseSystemInfo } from '../../api/base/getBaseSystemInfo'
import { preloadWebviews, PreloadWebviewObject } from './preLoad'
interface RegisterPageOptions {
url: string
......@@ -39,7 +40,29 @@ export function registerPage({
if (webview) {
initEntry()
}
// TODO preloadWebview
if (preloadWebviews[url]) {
webview = preloadWebviews[url]
const _webview = webview as PreloadWebviewObject
if (_webview.__page__) {
// 该预载页面已处于显示状态,不再使用该预加载页面,直接新开
if (getCurrentPages().find((page) => page === _webview.__page__)) {
if (process.env.NODE_ENV !== 'production') {
console.log(
`[uni-app] preloadWebview(${path},${_webview.id}) already in use`
)
}
webview = undefined
} else {
// TODO eventChannel
addCurrentPage(_webview.__page__)
if (process.env.NODE_ENV !== 'production') {
console.log(`[uni-app] reuse preloadWebview(${path},${_webview.id})`)
}
return _webview
}
}
}
const routeOptions = initRouteOptions(path, openType)
......@@ -82,7 +105,12 @@ export function registerPage({
initPageOptions(routeOptions)
)
} else {
vm && addCurrentPage(vm)
initPageVm(vm!, pageInstance)
addCurrentPage(vm!)
if ((webview as any).__preload__) {
;(webview as any).__page__ = vm
}
}
return webview
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册