提交 7210b660 编写于 作者: fxy060608's avatar fxy060608

feat(v3): onPageScroll,onReachBottom

上级 a85a6788
......@@ -3588,6 +3588,8 @@ var serviceContext = (function () {
const TITLEBAR_HEIGHT = 44;
const ON_REACH_BOTTOM_DISTANCE = 50;
const VIEW_WEBVIEW_PATH = '_www/__uniappview.html';
const V_FOR = 'f';
......@@ -6358,18 +6360,6 @@ var serviceContext = (function () {
}, delay);
}
const PAGE_CREATE = 2;
const MOUNTED_DATA = 4;
const UPDATED_DATA = 6;
const PAGE_CREATED = 10;
const UI_EVENT = 20;
const VD_SYNC = 'vdSync';
const WEBVIEW_READY = 'webviewReady';
const VD_SYNC_CALLBACK = 'vdSyncCallback';
const pageFactory = Object.create(null);
function definePage (name, createPageVueComponent) {
......@@ -6488,16 +6478,6 @@ var serviceContext = (function () {
{
if (!webview.nvue) {
const pageId = webview.id;
// 通知页面已开始创建
UniServiceJSBridge.publishHandler(VD_SYNC, {
data: [
[PAGE_CREATE, [pageId, route]]
],
options: {
timestamp: Date.now()
}
}, [pageId]);
try {
createPage(route, pageId, query, pageInstance).$mount();
} catch (e) {
......@@ -8728,6 +8708,101 @@ var serviceContext = (function () {
on('onWebInvokeAppService', onWebInvokeAppService);
}
const callbacks$a = {};
function createCallbacks (namespace) {
let scopedCallbacks = callbacks$a[namespace];
if (!scopedCallbacks) {
scopedCallbacks = {
id: 1,
callbacks: Object.create(null)
};
callbacks$a[namespace] = scopedCallbacks;
}
return {
get (id) {
return scopedCallbacks.callbacks[id]
},
pop (id) {
const callback = scopedCallbacks.callbacks[id];
if (callback) {
delete scopedCallbacks.callbacks[id];
}
return callback
},
push (callback) {
const id = scopedCallbacks.id++;
scopedCallbacks.callbacks[id] = callback;
return id
}
}
}
function initSubscribe (subscribe, {
getApp,
getCurrentPages
}) {
function createPageEvent (eventType) {
return function (args, pageId) {
pageId = parseInt(pageId);
const pages = getCurrentPages();
const page = pages.find(page => page.$page.id === pageId);
if (page) {
callPageHook(page, eventType, args);
} else {
console.error(`Not Found:Page[${pageId}]`);
}
}
}
const requestComponentInfoCallbacks = createCallbacks('requestComponentInfo');
function onRequestComponentInfo ({
reqId,
res
}) {
const callback = requestComponentInfoCallbacks.pop(reqId);
if (callback) {
callback(res);
}
}
const requestComponentObserverCallbacks = createCallbacks('requestComponentObserver');
function onRequestComponentObserver ({
reqId,
reqEnd,
res
}) {
const callback = requestComponentObserverCallbacks.get(reqId);
if (callback) {
if (reqEnd) {
requestComponentObserverCallbacks.pop(reqId);
return
}
callback(res);
}
}
subscribe('onPageScroll', createPageEvent('onPageScroll'));
subscribe('onReachBottom', createPageEvent('onReachBottom'));
subscribe('onRequestComponentInfo', onRequestComponentInfo);
subscribe('onRequestComponentObserver', onRequestComponentObserver);
}
const PAGE_CREATE = 2;
const MOUNTED_DATA = 4;
const UPDATED_DATA = 6;
const PAGE_CREATED = 10;
const UI_EVENT = 20;
const VD_SYNC = 'vdSync';
const WEBVIEW_READY = 'webviewReady';
const VD_SYNC_CALLBACK = 'vdSyncCallback';
function perf (type, startTime) {
/* eslint-disable no-undef */
startTime = startTime || __UniServiceStartTime__;
......@@ -8735,12 +8810,18 @@ var serviceContext = (function () {
console.log(`[PERF][${endTime}] ${type} 耗时[${Date.now() - startTime}]`);
}
function onWebviewReady (data, pageId) {
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] onWebviewReady.preloadWebview' + (preloadWebview && preloadWebview.id));
}
let isLaunchWebviewReady = false; // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android)
function onWebviewReady (data, pageId) {
const isLaunchWebview = pageId === '1';
if (isLaunchWebview && isLaunchWebviewReady) {
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] onLaunchWebviewReady.prevent');
}
return
}
if (isLaunchWebview) { // 首页
isLaunchWebviewReady = true;
setPreloadWebview(plus.webview.getLaunchWebview());
} else if (!preloadWebview) { // preloadWebview 不存在,重新加载一下
setPreloadWebview(plus.webview.getWebviewById(pageId));
......@@ -8802,22 +8883,35 @@ var serviceContext = (function () {
function initSubscribeHandlers () {
const {
subscribe,
publishHandler,
subscribeHandler
} = UniServiceJSBridge;
initSubscribe(subscribe, {
getApp,
getCurrentPages
});
registerPlusMessage('subscribeHandler', (data) => {
subscribeHandler(data.type, data.data, data.pageId);
});
// TODO 检测目标 preloadWebview 是否已准备好,因为 preloadWebview 准备好时,此处代码还没执行
subscribe(WEBVIEW_READY, onWebviewReady);
const entryPagePath = '/' + __uniConfig.entryPagePath;
const routeOptions = __uniRoutes.find(route => route.path === entryPagePath);
if (!routeOptions.meta.isNVue) { // 首页是 vue
// 防止首页 webview 初始化过早, service 还未开始监听
publishHandler(WEBVIEW_READY, Object.create(null), [1]);
}
subscribe(VD_SYNC, onVdSync);
subscribe(VD_SYNC_CALLBACK, onVdSyncCallback);
}
let appCtx;
function getApp () {
function getApp$1 () {
return appCtx
}
......@@ -8913,7 +9007,7 @@ var serviceContext = (function () {
appCtx.globalData = appVm.$options.globalData || {};
initOn(UniServiceJSBridge.on, {
getApp,
getApp: getApp$1,
getCurrentPages: getCurrentPages$1
});
......@@ -9012,7 +9106,6 @@ var serviceContext = (function () {
[UI_EVENT]: function onUIEvent (vdBatchEvent, vd) {
vdBatchEvent.forEach(([cid, nid, event]) => {
nid = String(nid);
console.log(`[EVENT]`, cid, nid, event);
event.preventDefault = noop;
event.stopPropagation = noop;
const target = vd.elements.find(target => target.cid === cid && target.nid === nid);
......@@ -9172,7 +9265,6 @@ var serviceContext = (function () {
}
diff(this._$newData, this._$data, this._$vdMountedData);
this._$data = JSON.parse(JSON.stringify(this._$newData));
console.log(`[${this._$id}] mounted ` + Date.now());
if (this.mpType === 'page') {
// 页面 mounted 之后,第一次同步数据
this._$vd.flush();
......@@ -9189,7 +9281,6 @@ var serviceContext = (function () {
// 子组件 updated 时,可能会增加父组件的 diffData,如 slot 等情况
diff(this._$newData, this._$data, this._$vdUpdatedData);
this._$data = JSON.parse(JSON.stringify(this._$newData));
console.log(`[${this._$id}] updated ` + Date.now());
// setTimeout 一下再 nextTick( 直接 nextTick 的话,会紧接着该 updated 做 flush,导致父组件 updated 数据被丢弃)
this._$vd.initialized && setTimeout(() => {
this.$nextTick(this._$vd.flush.bind(this._$vd));
......@@ -9218,7 +9309,6 @@ var serviceContext = (function () {
this._$vd.addVm(this);
this._$vdMountedData = Object.create(null);
this._$setData(MOUNTED_DATA, this._$vdMountedData);
console.log(`[${this._$id}] beforeCreate ` + Date.now());
this._$data = Object.create(null);
this._$newData = Object.create(null);
}
......@@ -9229,7 +9319,6 @@ var serviceContext = (function () {
}
this._$vdUpdatedData = Object.create(null);
this._$setData(UPDATED_DATA, this._$vdUpdatedData);
console.log(`[${this._$id}] beforeUpdate ` + Date.now());
this._$newData = Object.create(null);
},
beforeDestroy () {
......@@ -9291,6 +9380,10 @@ var serviceContext = (function () {
return ((this._$newData[id] || (this._$newData[id] = {}))[V_ELSE_IF] = !!value)
}
function hasLifecycleHook (vueOptions = {}, hook) {
return Array.isArray(vueOptions[hook]) && vueOptions[hook].length
}
/* @flow */
const LIFECYCLE_HOOKS = [
......@@ -9349,6 +9442,27 @@ var serviceContext = (function () {
});
}
function parsePageCreateOptions (vm, route) {
const pagePath = '/' + route;
const routeOptions = __uniRoutes.find(route => route.path === pagePath);
const windowOptions = Object.assign({}, __uniConfig.window, routeOptions.window);
const disableScroll = windowOptions.disableScroll === true ? 1 : 0;
const onReachBottomDistance = hasOwn(windowOptions, 'onReachBottomDistance')
? parseInt(windowOptions.onReachBottomDistance)
: ON_REACH_BOTTOM_DISTANCE;
const onPageScroll = hasLifecycleHook(vm.$options, 'onPageScroll') ? 1 : 0;
const onPageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom') ? 1 : 0;
return {
disableScroll,
onPageScroll,
onPageReachBottom,
onReachBottomDistance
}
}
function initLifecycle (Vue) {
lifecycleMixin(Vue);
......@@ -9358,6 +9472,18 @@ var serviceContext = (function () {
this.$scope = this.$options.pageInstance;
this.$scope.$vm = this;
delete this.$options.pageInstance;
const route = this.$scope.route;
const pageId = this.$scope.$page.id;
// 通知页面已开始创建
UniServiceJSBridge.publishHandler(VD_SYNC, {
data: [
[PAGE_CREATE, [pageId, route, parsePageCreateOptions(this, route)]]
],
options: {
timestamp: Date.now()
}
}, [pageId]);
}
},
created () {
......@@ -9406,7 +9532,7 @@ var serviceContext = (function () {
__registerApp: registerApp,
__registerPage: registerPage,
uni: uni$1,
getApp,
getApp: getApp$1,
getCurrentPages: getCurrentPages$1
};
......
此差异已折叠。
......@@ -17,7 +17,7 @@ const {
parseComponents
} = require('./util')
function getDefineComponents (components) {
function getDefineComponents(components) {
return components.map(({
name,
source
......@@ -26,7 +26,7 @@ function getDefineComponents (components) {
const appVueFilePath = path.resolve(process.env.UNI_INPUT_DIR, 'app.vue')
function getStylesCode (loaderContext) {
function getStylesCode(loaderContext) {
if (!fs.existsSync(appVueFilePath)) {
return
}
......@@ -71,9 +71,9 @@ function getStylesCode (loaderContext) {
const needsHotReload = false
const id = hash(
isProduction
? (shortFilePath + '\n' + source)
: shortFilePath
isProduction ?
(shortFilePath + '\n' + source) :
shortFilePath
)
stylesCode = genStylesCode(
......@@ -83,17 +83,24 @@ function getStylesCode (loaderContext) {
resourcePath,
stringifyRequest,
needsHotReload,
isServer || isShadow // needs explicit injection?
true // needs explicit injection?
)
}
return stylesCode.replace(/main\.js/g, 'App.vue')
}
module.exports = function (source, map) {
// 解析自定义组件,及 App 样式
return `import 'uni-pages'
${getStylesCode(this)}
${getDefineComponents(parseComponents(source, traverse)).join('\n')}
UniViewJSBridge.publishHandler('webviewReady')
module.exports = function(source, map) {
return `
import 'uni-pages'
function initView(){
${getStylesCode(this)}
${getDefineComponents(parseComponents(source, traverse)).join('\n')}
UniViewJSBridge.publishHandler('webviewReady')
}
if(typeof plus !== 'undefined'){
initView()
} else {
document.addEventListener('plusready',initView)
}
`
}
......@@ -485,7 +485,9 @@ module.exports = function (pagesJson, userManifestJson) {
'description': 'UniNView原生渲染'
}
// TODO 需要考虑 condition
manifestJson.plus.launchwebview.id = '1' // 首页 id 固定 为 1
manifestJson.plus.launchwebview.id = '1' // 首页 id 固定 为 1
// 删除首页 style 中的 uni-app 配置(不注入 app-view.js)
delete manifestJson.plus.launchwebview['uni-app']
if (appJson.page[appJson.entryPagePath].nvue) { // 首页是 nvue
manifestJson.launch_path = '' // 首页地址为空
......
......@@ -9,7 +9,8 @@ export default function initSubscribe (subscribe, {
getCurrentPages
}) {
function createPageEvent (eventType) {
return function (args, pageId) {
return function (args, pageId) {
pageId = parseInt(pageId)
const pages = getCurrentPages()
const page = pages.find(page => page.$page.id === pageId)
if (page) {
......@@ -47,9 +48,12 @@ export default function initSubscribe (subscribe, {
}
callback(res)
}
}
if (__PLATFORM__ === 'h5') {
subscribe('onPageReady', createPageEvent('onReady'))
}
subscribe('onPageReady', createPageEvent('onReady'))
subscribe('onPageScroll', createPageEvent('onPageScroll'))
subscribe('onReachBottom', createPageEvent('onReachBottom'))
......
import {
isPlainObject,
supportsPassive
} from 'uni-shared'
import {
hasLifecycleHook
} from 'uni-helpers/index'
import {
NAVBAR_HEIGHT,
TABBAR_HEIGHT
} from 'uni-helpers/constants'
import subscribeApis from 'uni-api-subscribe'
import {
pageScrollTo,
disableScroll,
createScrollListener
pageScrollTo
} from './scroll'
import subscribeApis from 'uni-api-subscribe'
const passiveOptions = supportsPassive ? {
passive: false
} : false
function updateCssVar (vm) {
if (uni.canIUse('css.var')) {
const pageVm = vm.$parent.$parent
const windowTop = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' && pageVm.navigationBar.type !== 'float' ? (NAVBAR_HEIGHT +
'px')
: '0px'
const windowBottom = getApp().$children[0].showTabBar ? (TABBAR_HEIGHT + 'px') : '0px'
const style = document.documentElement.style
style.setProperty('--window-top', windowTop)
style.setProperty('--window-bottom', windowBottom)
console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-top=${windowTop}`)
console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-bottom=${windowBottom}`)
}
}
import initPlatformSubscribe from 'uni-platform/view/bridge/subscribe'
export default function initSubscribe (subscribe) {
Object.keys(subscribeApis).forEach(name => {
......@@ -46,52 +13,5 @@ export default function initSubscribe (subscribe) {
subscribe('pageScrollTo', pageScrollTo)
if (__PLATFORM__ === 'h5') {
let scrollListener = false
let disableScrollListener = false
subscribe('onPageLoad', vm => { // 用户 onLoad 之前 update
updateCssVar(vm)
})
subscribe('onPageShow', vm => {
const pageVm = vm.$parent.$parent
if (vm._isMounted) { // 非首次 show 才 update(首次 show 的时候在 onPageLoad 中触发了)
updateCssVar(vm)
}
if (disableScrollListener) {
document.removeEventListener('touchmove', disableScrollListener, passiveOptions)
}
if (pageVm.disableScroll) {
disableScrollListener = disableScroll
document.addEventListener('touchmove', disableScrollListener, passiveOptions)
}
const enablePageScroll = hasLifecycleHook(vm.$options, 'onPageScroll')
const enablePageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom')
const onReachBottomDistance = pageVm.onReachBottomDistance
const enableTransparentTitleNView = (isPlainObject(pageVm.titleNView) && pageVm.titleNView.type ===
'transparent') || (isPlainObject(pageVm.navigationBar) && pageVm.navigationBar.type === 'transparent')
if (scrollListener) {
document.removeEventListener('scroll', scrollListener)
}
if (enableTransparentTitleNView || enablePageScroll || enablePageReachBottom) { // 初始化 scroll 监听
scrollListener = createScrollListener(vm.$page.id, {
enablePageScroll,
enablePageReachBottom,
onReachBottomDistance,
enableTransparentTitleNView
})
requestAnimationFrame(function () { // 避免监听太早,直接触发了 scroll
document.addEventListener('scroll', scrollListener)
})
}
})
}
}
initPlatformSubscribe(subscribe)
}
......@@ -7,6 +7,8 @@ export const ANI_CLOSE = downgrade ? 'slide-out-right' : 'pop-out'
export const TITLEBAR_HEIGHT = 44
export const ON_REACH_BOTTOM_DISTANCE = 50
export const VIEW_WEBVIEW_PATH = '_www/__uniappview.html'
export const V_FOR = 'f'
......
......@@ -7,11 +7,6 @@ import {
navigateFinish
} from './navigator'
import {
VD_SYNC,
PAGE_CREATE
} from '../../constants'
import tabBar from '../framework/tab-bar'
import {
......@@ -108,16 +103,6 @@ export function registerPage ({
if (__PLATFORM__ === 'app-plus') {
if (!webview.nvue) {
const pageId = webview.id
// 通知页面已开始创建
UniServiceJSBridge.publishHandler(VD_SYNC, {
data: [
[PAGE_CREATE, [pageId, route]]
],
options: {
timestamp: Date.now()
}
}, [pageId])
try {
createPage(route, pageId, query, pageInstance).$mount()
} catch (e) {
......
......@@ -41,7 +41,6 @@ export function initData (Vue) {
}
diff(this._$newData, this._$data, this._$vdMountedData)
this._$data = JSON.parse(JSON.stringify(this._$newData))
console.log(`[${this._$id}] mounted ` + Date.now())
if (this.mpType === 'page') {
// 页面 mounted 之后,第一次同步数据
this._$vd.flush()
......@@ -58,7 +57,6 @@ export function initData (Vue) {
// 子组件 updated 时,可能会增加父组件的 diffData,如 slot 等情况
diff(this._$newData, this._$data, this._$vdUpdatedData)
this._$data = JSON.parse(JSON.stringify(this._$newData))
console.log(`[${this._$id}] updated ` + Date.now())
// setTimeout 一下再 nextTick( 直接 nextTick 的话,会紧接着该 updated 做 flush,导致父组件 updated 数据被丢弃)
this._$vd.initialized && setTimeout(() => {
this.$nextTick(this._$vd.flush.bind(this._$vd))
......@@ -87,7 +85,6 @@ export function initData (Vue) {
this._$vd.addVm(this)
this._$vdMountedData = Object.create(null)
this._$setData(MOUNTED_DATA, this._$vdMountedData)
console.log(`[${this._$id}] beforeCreate ` + Date.now())
this._$data = Object.create(null)
this._$newData = Object.create(null)
}
......@@ -98,7 +95,6 @@ export function initData (Vue) {
}
this._$vdUpdatedData = Object.create(null)
this._$setData(UPDATED_DATA, this._$vdUpdatedData)
console.log(`[${this._$id}] beforeUpdate ` + Date.now())
this._$newData = Object.create(null)
},
beforeDestroy () {
......
import {
hasOwn
} from 'uni-shared'
import {
hasLifecycleHook
} from 'uni-helpers/index'
import {
callPageHook
} from 'uni-core/service/plugins/util'
......@@ -7,6 +15,37 @@ import {
}
from 'uni-core/service/plugins/lifecycle'
import {
VD_SYNC,
PAGE_CREATE
} from '../../../constants'
import {
ON_REACH_BOTTOM_DISTANCE
}
from '../../constants'
function parsePageCreateOptions (vm, route) {
const pagePath = '/' + route
const routeOptions = __uniRoutes.find(route => route.path === pagePath)
const windowOptions = Object.assign({}, __uniConfig.window, routeOptions.window)
const disableScroll = windowOptions.disableScroll === true ? 1 : 0
const onReachBottomDistance = hasOwn(windowOptions, 'onReachBottomDistance')
? parseInt(windowOptions.onReachBottomDistance)
: ON_REACH_BOTTOM_DISTANCE
const onPageScroll = hasLifecycleHook(vm.$options, 'onPageScroll') ? 1 : 0
const onPageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom') ? 1 : 0
return {
disableScroll,
onPageScroll,
onPageReachBottom,
onReachBottomDistance
}
}
export function initLifecycle (Vue) {
lifecycleMixin(Vue)
......@@ -16,6 +55,18 @@ export function initLifecycle (Vue) {
this.$scope = this.$options.pageInstance
this.$scope.$vm = this
delete this.$options.pageInstance
const route = this.$scope.route
const pageId = this.$scope.$page.id
// 通知页面已开始创建
UniServiceJSBridge.publishHandler(VD_SYNC, {
data: [
[PAGE_CREATE, [pageId, route, parsePageCreateOptions(this, route)]]
],
options: {
timestamp: Date.now()
}
}, [pageId])
}
},
created () {
......
......@@ -22,7 +22,6 @@ const handleVdData = {
[UI_EVENT]: function onUIEvent (vdBatchEvent, vd) {
vdBatchEvent.forEach(([cid, nid, event]) => {
nid = String(nid)
console.log(`[EVENT]`, cid, nid, event)
event.preventDefault = noop
event.stopPropagation = noop
const target = vd.elements.find(target => target.cid === cid && target.nid === nid)
......
import initSubscribe from 'uni-core/service/bridge/subscribe'
import {
VD_SYNC,
VD_SYNC_CALLBACK,
......@@ -16,15 +18,28 @@ import onVdSyncCallback from './on-vd-sync-callback'
export function initSubscribeHandlers () {
const {
subscribe,
publishHandler,
subscribeHandler
} = UniServiceJSBridge
initSubscribe(subscribe, {
getApp,
getCurrentPages
})
registerPlusMessage('subscribeHandler', (data) => {
subscribeHandler(data.type, data.data, data.pageId)
})
// TODO 检测目标 preloadWebview 是否已准备好,因为 preloadWebview 准备好时,此处代码还没执行
subscribe(WEBVIEW_READY, onWebviewReady)
const entryPagePath = '/' + __uniConfig.entryPagePath
const routeOptions = __uniRoutes.find(route => route.path === entryPagePath)
if (!routeOptions.meta.isNVue) { // 首页是 vue
// 防止首页 webview 初始化过早, service 还未开始监听
publishHandler(WEBVIEW_READY, Object.create(null), [1])
}
subscribe(VD_SYNC, onVdSync)
subscribe(VD_SYNC_CALLBACK, onVdSyncCallback)
}
......@@ -8,12 +8,18 @@ import {
perf
} from '../perf'
export default function onWebviewReady (data, pageId) {
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] onWebviewReady.preloadWebview' + (preloadWebview && preloadWebview.id))
}
let isLaunchWebviewReady = false // 目前首页双向确定 ready,可能会导致触发两次 onWebviewReady(主要是 Android)
export default function onWebviewReady (data, pageId) {
const isLaunchWebview = pageId === '1'
if (isLaunchWebview && isLaunchWebviewReady) {
if (process.env.NODE_ENV !== 'production') {
console.log('[uni-app] onLaunchWebviewReady.prevent')
}
return
}
if (isLaunchWebview) { // 首页
isLaunchWebviewReady = true
setPreloadWebview(plus.webview.getLaunchWebview())
} else if (!preloadWebview) { // preloadWebview 不存在,重新加载一下
setPreloadWebview(plus.webview.getWebviewById(pageId))
......
import {
supportsPassive
} from 'uni-shared'
import {
disableScroll as disableScrollListener,
createScrollListener
} from 'uni-core/view/bridge/subscribe/scroll'
import {
ON_PAGE_CREATE
} from '../../constants'
import {
WEBVIEW_READY
} from '../../../constants'
const passiveOptions = supportsPassive ? {
passive: false
} : false
function onPageCreate ({
disableScroll,
onPageScroll,
onPageReachBottom,
onReachBottomDistance
}, pageId) {
if (disableScroll) {
document.addEventListener('touchmove', disableScrollListener, passiveOptions)
} else if (onPageScroll || onPageReachBottom) {
requestAnimationFrame(function () { // 避免监听太早,直接触发了 scroll
document.addEventListener('scroll', createScrollListener(pageId, {
enablePageScroll: onPageScroll,
enablePageReachBottom: onPageReachBottom,
onReachBottomDistance
}))
})
}
}
function onWebviewReady () { // service 主动发起检测
UniViewJSBridge.publishHandler('webviewReady')
}
export default function initSubscribe (subscribe) {
subscribe(WEBVIEW_READY, onWebviewReady)
subscribe(ON_PAGE_CREATE, onPageCreate)
}
export const ON_PAGE_CREATE = 'onPageCreate'
......@@ -9,6 +9,10 @@ import {
VD_SYNC_CALLBACK
} from '../../../constants'
import {
ON_PAGE_CREATE
} from '../../constants'
import {
VDomSync
} from './vdom-sync'
......@@ -27,7 +31,7 @@ let PageVueComponent
const handleData = {
[PAGE_CREATE]: function onPageCreate (data) {
const [pageId, pagePath] = data
const [pageId, pagePath, pageOptions] = data
document.title = `${pagePath}[${pageId}]`
// 设置当前页面伪对象,方便其他地方使用 getCurrentPages 获取当前页面 id,route
setCurrentPage(pageId, pagePath)
......@@ -35,6 +39,8 @@ const handleData = {
PageVueComponent = getPageVueComponent(pagePath)
// 生成当前页面 vd
vd = new VDomSync(pageId)
// 通知页面创建,根据当前页面配置信息,初始化部分事件
UniViewJSBridge.subscribeHandler(ON_PAGE_CREATE, pageOptions, pageId)
},
[MOUNTED_DATA]: function onMounted (data) {
vd.addVData.apply(vd, data)
......@@ -95,7 +101,6 @@ export function initData (Vue) {
}
if (this._$vd) {
this._$vd.initVm(this)
console.log(`[${this._$id}] beforeCreate ` + Date.now())
}
}
})
......
......@@ -56,7 +56,6 @@ export class VDomSync {
}
flush () {
console.log('update....', this.addBatchVData, this.updateBatchVData)
this.updateBatchVData.forEach(([cid, data]) => {
const vm = this.vms[cid]
if (!vm) {
......
import {
isPlainObject,
supportsPassive
} from 'uni-shared'
import {
hasLifecycleHook
} from 'uni-helpers/index'
import {
NAVBAR_HEIGHT,
TABBAR_HEIGHT
} from 'uni-helpers/constants'
import {
disableScroll,
createScrollListener
} from 'uni-core/view/bridge/subscribe/scroll'
const passiveOptions = supportsPassive ? {
passive: false
} : false
function updateCssVar (vm) {
if (uni.canIUse('css.var')) {
const pageVm = vm.$parent.$parent
const windowTop = pageVm.showNavigationBar && pageVm.navigationBar.type !== 'transparent' && pageVm.navigationBar.type !==
'float' ? (NAVBAR_HEIGHT +
'px')
: '0px'
const windowBottom = getApp().$children[0].showTabBar ? (TABBAR_HEIGHT + 'px') : '0px'
const style = document.documentElement.style
style.setProperty('--window-top', windowTop)
style.setProperty('--window-bottom', windowBottom)
console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-top=${windowTop}`)
console.debug(`${vm.$page.route}[${vm.$page.id}]:--window-bottom=${windowBottom}`)
}
}
export default function initSubscribe (subscribe) {
let scrollListener = false
let disableScrollListener = false
subscribe('onPageLoad', vm => { // 用户 onLoad 之前 update
updateCssVar(vm)
})
subscribe('onPageShow', vm => {
const pageVm = vm.$parent.$parent
if (vm._isMounted) { // 非首次 show 才 update(首次 show 的时候在 onPageLoad 中触发了)
updateCssVar(vm)
}
if (disableScrollListener) {
document.removeEventListener('touchmove', disableScrollListener, passiveOptions)
}
if (pageVm.disableScroll) {
disableScrollListener = disableScroll
document.addEventListener('touchmove', disableScrollListener, passiveOptions)
}
const enablePageScroll = hasLifecycleHook(vm.$options, 'onPageScroll')
const enablePageReachBottom = hasLifecycleHook(vm.$options, 'onReachBottom')
const onReachBottomDistance = pageVm.onReachBottomDistance
const enableTransparentTitleNView = (isPlainObject(pageVm.titleNView) && pageVm.titleNView.type ===
'transparent') || (isPlainObject(pageVm.navigationBar) && pageVm.navigationBar.type === 'transparent')
if (scrollListener) {
document.removeEventListener('scroll', scrollListener)
}
if (enableTransparentTitleNView || enablePageScroll || enablePageReachBottom) { // 初始化 scroll 监听
scrollListener = createScrollListener(vm.$page.id, {
enablePageScroll,
enablePageReachBottom,
onReachBottomDistance,
enableTransparentTitleNView
})
requestAnimationFrame(function () { // 避免监听太早,直接触发了 scroll
document.addEventListener('scroll', scrollListener)
})
}
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册