界面渲染在數(shù)據(jù)加載之前,出現(xiàn)優(yōu)先渲染界面,而數(shù)據(jù)加載完后,界面不再渲染。
通過數(shù)據(jù)監(jiān)聽事件,當(dāng)data中數(shù)據(jù)被改變時,進(jìn)行監(jiān)聽,并進(jìn)行數(shù)據(jù)渲染。
swatch事件監(jiān)聽
新建一個swatch.js的工具類,源碼如下:
// watch.js
const observe = (obj, key, watchFun, deep, page) => {
let oldVal = obj[key]
// 如果監(jiān)聽對象是object類型并且指定deep(深度監(jiān)聽)
if (oldVal !== null && typeof oldVal === 'object' && deep) {
// 遞歸子集,依次執(zhí)行observe()
Object.keys(oldVal).forEach(item => {
observe(oldVal, item, watchFun, deep, page)
})
}
// 使用Object.defineProperty()劫持?jǐn)?shù)據(jù)的寫操作,在監(jiān)聽對象改變后執(zhí)行傳入的watchFun
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set(value) {
if (value === oldVal) return
watchFun.call(page, value, oldVal)
oldVal = value
},
get() {
return oldVal
}
})
}
export const setWatcher = (page) => {
// 頁面里的data字段
const data = page.data
// 頁面里的watch字段
const watch = page.watch
// 對watch里列舉的每一個字段(需要監(jiān)聽的字段)執(zhí)行observe()
Object.keys(watch).forEach(key => {
let targetData = data
const targetKey = key
// 支持deep深度監(jiān)聽,使用deep時需要配合handler使用,否則直接編寫函數(shù)
const watchFun = watch[key].handler || watch[key]
const deep = watch[key].deep
observe(targetData, targetKey, watchFun, deep, page)
})
}
在需要進(jìn)行渲染的界面,進(jìn)行數(shù)據(jù)監(jiān)聽
import {setWatcher} from '../../utils/watch.js'
onLoad(){
setWatcher(this)
},
watch: {
shuju(val) {
console.log('數(shù)據(jù)改變了')
}
},