在Vue中我们有如下生命周期方法:

给vue增加一个扩展函数
- Vue合并策略
在Vue中使用mixins时会发现, data,props,methods是同名属性覆盖合并。生命周期函数是合并调用。
这个原理就是 “合并策略” 导致的。
在Vue中,提供了一个api, Vue.config.optionMergeStrategies,可以通过这个api去自定义选项的合并策略。 - 我们可以利用optionMergeStrategies 这个属性来给 Vue实例增加一个扩展函数。
import Vue from 'vue'
// 通知所有组件页面状态发生了变化
const notifyVisibilityChange = (lifeCycleName, vm) => {
// 生命周期函数会存在$options中,通过$options[lifeCycleName]获取生命周期
const lifeCycles = vm.$options[lifeCycleName]
// 因为使用了created的合并策略,所以是一个数组
if (lifeCycles && lifeCycles.length) {
// 遍历 lifeCycleName对应的生命周期函数列表,依次执行
lifeCycles.forEach(lifecycle => {
lifecycle.call(vm)
})
}
// 遍历所有的子组件,然后依次递归执行
if (vm.$children && vm.$children.length) {
vm.$children.forEach(child => {
notifyVisibilityChange(lifeCycleName, child)
})
}
}
/**
* 添加生命周期钩子函数
* @param {*} rootVm vue 根实例,在页面显示隐藏时候,通过root向下通知
*/
export function init() {
const optionMergeStrategies = Vue.config.optionMergeStrategies
/*
定义了两个生命周期函数 pageVisible, pageHidden
为什么要赋值为 optionMergeStrategies.created呢
这个相当于指定 pageVisible, pageHidden 的合并策略与 created的相同(其他生命周期函数都一样)
*/
optionMergeStrategies.pageVisible = optionMergeStrategies.beforeCreate
optionMergeStrategies.pageHidden = optionMergeStrategies.created
}
/**
* 将事件变化绑定到根节点上面
* @param {*} rootVm
*/
export function bind(rootVm) {
window.addEventListener('visibilitychange', () => {
// 判断调用哪个生命周期函数
let lifeCycleName = undefined
if (document.visibilityState === 'hidden') {
lifeCycleName = 'pageHidden'
} else if (document.visibilityState === 'visible') {
lifeCycleName = 'pageVisible'
}
if (lifeCycleName) {
// 通过所有组件生命周期发生变化了
notifyVisibilityChange(lifeCycleName, rootVm)
}
})
}
使用
- 在main.js主入口文件引入
import { init, bind } from './utils/custom-life-cycle'
// 初始化生命周期函数, 必须在Vue实例化之前确定合并策略
init()
const vm = new Vue({
router,
render: h => h(App)
}).$mount('#app')
// 将rootVm 绑定到生命周期函数监听里面
bind(vm)
- 在需要的地方监听生命周期函数
export default {
pageVisible() {
console.log('页面显示出来了')
},
pageHidden() {
console.log('页面隐藏了')
}
}
理解
这种方式不仅可以作用在跟实例上,也可以作用于某个页面。微信小程序的 onShow();onHidden() 实现也类似于这样吧。
网友评论