You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
4.3 KiB
177 lines
4.3 KiB
|
3 years ago
|
import Vue from 'vue'
|
||
|
|
|
||
|
|
import {
|
||
|
|
VD_SYNC,
|
||
|
|
PAGE_CREATE,
|
||
|
|
MOUNTED_DATA,
|
||
|
|
UPDATED_DATA,
|
||
|
|
PAGE_CREATED,
|
||
|
|
VD_SYNC_CALLBACK
|
||
|
|
} from '../../../constants'
|
||
|
|
|
||
|
|
import {
|
||
|
|
ON_PAGE_CREATE
|
||
|
|
} from '../../constants'
|
||
|
|
|
||
|
|
import {
|
||
|
|
VDomSync
|
||
|
|
} from './vdom-sync'
|
||
|
|
|
||
|
|
import {
|
||
|
|
setCurrentPage
|
||
|
|
} from '../page'
|
||
|
|
|
||
|
|
import {
|
||
|
|
getPageVueComponent
|
||
|
|
} from '../../../page-factory'
|
||
|
|
|
||
|
|
export let vd
|
||
|
|
|
||
|
|
let PageVueComponent
|
||
|
|
|
||
|
|
const handleData = {
|
||
|
|
[PAGE_CREATE]: function onPageCreate (data) {
|
||
|
|
const [pageId, pagePath, pageOptions] = data
|
||
|
|
document.title = `${pagePath}[${pageId}]`
|
||
|
|
|
||
|
|
updateRootFontSize()
|
||
|
|
|
||
|
|
// 设置当前页面伪对象,方便其他地方使用 getCurrentPages 获取当前页面 id,route
|
||
|
|
setCurrentPage(pageId, pagePath)
|
||
|
|
// 通知页面创建,根据当前页面配置信息,初始化部分事件
|
||
|
|
UniViewJSBridge.subscribeHandler(ON_PAGE_CREATE, pageOptions, pageId)
|
||
|
|
// 初始化当前页面 VueComponent(生成页面样式代码)
|
||
|
|
PageVueComponent = getPageVueComponent(pagePath)
|
||
|
|
// 生成当前页面 vd
|
||
|
|
vd = new VDomSync(pageId, {
|
||
|
|
version: pageOptions.version
|
||
|
|
})
|
||
|
|
},
|
||
|
|
[MOUNTED_DATA]: function onMounted (data) {
|
||
|
|
vd.addVData.apply(vd, data)
|
||
|
|
},
|
||
|
|
[UPDATED_DATA]: function onUpdated (data) {
|
||
|
|
vd.updateVData.apply(vd, data)
|
||
|
|
},
|
||
|
|
[PAGE_CREATED]: function onPageCreated (data) {
|
||
|
|
const [pageId, pagePath, pageQuery] = data
|
||
|
|
const page = getCurrentPages()[0]
|
||
|
|
page.options = pageQuery || {}
|
||
|
|
page.$vm = new PageVueComponent({
|
||
|
|
mpType: 'page',
|
||
|
|
pageId,
|
||
|
|
pagePath,
|
||
|
|
pageQuery
|
||
|
|
}).$mount('#app')
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function broadcast (vm, componentName, eventName, ...params) {
|
||
|
|
vm.$children.forEach(child => {
|
||
|
|
const name = child.$options.name && child.$options.name.replace(/^VUni/, '')
|
||
|
|
if (~componentName.indexOf(name)) {
|
||
|
|
child.$emit(eventName, ...params)
|
||
|
|
}
|
||
|
|
broadcast(child, componentName, eventName, ...params)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
const NATIVE_COMPONENTS = ['Camera', 'LivePlayer', 'LivePusher', 'Map', 'Video', 'CoverView', 'CoverImage', 'Ad']
|
||
|
|
|
||
|
|
function updateView () {
|
||
|
|
const pages = getCurrentPages()
|
||
|
|
const pageVm = pages[0] && pages[0].$vm
|
||
|
|
pageVm && broadcast(
|
||
|
|
pageVm,
|
||
|
|
NATIVE_COMPONENTS,
|
||
|
|
'uni-view-update'
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
function updateRootFontSize () {
|
||
|
|
// 页面存在横竖屏切换时,预加载的 webview 的 fontSize 需要再次校正一下
|
||
|
|
const oldFontSize = document.documentElement.style.fontSize
|
||
|
|
const newFontSize = document.documentElement.clientWidth / 20 + 'px'
|
||
|
|
if (oldFontSize !== newFontSize) {
|
||
|
|
document.documentElement.style.fontSize = newFontSize
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
window.addEventListener('resize', () => {
|
||
|
|
// TODO 与之前逻辑保持一致,仅当前 webview 未被使用时,校准 fontSize,后续考虑动态旋转,调整rootfontSize
|
||
|
|
if (!getCurrentPages().length) {
|
||
|
|
updateRootFontSize()
|
||
|
|
}
|
||
|
|
updateView()
|
||
|
|
})
|
||
|
|
|
||
|
|
window.addEventListener('updateview', updateView)
|
||
|
|
|
||
|
|
function vdSync ({
|
||
|
|
data,
|
||
|
|
options
|
||
|
|
}) {
|
||
|
|
let isVdCallback = true
|
||
|
|
data.forEach(data => {
|
||
|
|
if (data[0] === PAGE_CREATE) { // 页面创建无需触发 callback
|
||
|
|
isVdCallback = false
|
||
|
|
}
|
||
|
|
handleData[data[0]](data[1])
|
||
|
|
})
|
||
|
|
vd.flush()
|
||
|
|
Vue.nextTick(() => {
|
||
|
|
// 清空本次 addBatchData
|
||
|
|
vd.clearAddBatchVData()
|
||
|
|
updateView()
|
||
|
|
isVdCallback && UniViewJSBridge.publishHandler(VD_SYNC_CALLBACK)
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
function getData (id, name) {
|
||
|
|
try {
|
||
|
|
return this.$r[id][name]
|
||
|
|
} catch (e) {
|
||
|
|
// console.error(this.$options.__file + `:[${this._$id}]$r[${id}][${name}] is undefined`)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* wxs change:prop
|
||
|
|
* @param {Object} id
|
||
|
|
* @param {Object} name
|
||
|
|
*/
|
||
|
|
function getChangeData (id, name) {
|
||
|
|
try {
|
||
|
|
const value = this.$r[id][name]
|
||
|
|
const wxsPropName = name.replace('change:', '')
|
||
|
|
this[wxsPropName] = value
|
||
|
|
this.$set(this.wxsProps, wxsPropName, value)
|
||
|
|
return value
|
||
|
|
} catch (e) {
|
||
|
|
// console.error(this.$options.__file + `:[${this._$id}]$r[${id}][${name}] is undefined`)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export function initData (Vue) {
|
||
|
|
Vue.prototype._$g = getData
|
||
|
|
Vue.prototype._$gc = getChangeData
|
||
|
|
|
||
|
|
UniViewJSBridge.subscribe(VD_SYNC, vdSync)
|
||
|
|
|
||
|
|
Object.defineProperty(Vue.prototype, '_$vd', {
|
||
|
|
get () {
|
||
|
|
return !this.$options.isReserved && vd
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
Vue.mixin({
|
||
|
|
beforeCreate () {
|
||
|
|
if (this.$options.mpType) {
|
||
|
|
this.mpType = this.$options.mpType
|
||
|
|
}
|
||
|
|
if (this._$vd) {
|
||
|
|
this._$vd.initVm(this)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|