给Vue扩展方法

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

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)
    }
  })
}

使用

  1. 在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)
  1. 在需要的地方监听生命周期函数
export default {
  pageVisible() {
    console.log('页面显示出来了')
  },
  pageHidden() {
    console.log('页面隐藏了')
  }
}

理解

这种方式不仅可以作用在跟实例上,也可以作用于某个页面。微信小程序的 onShow();onHidden() 实现也类似于这样吧。

你可能感兴趣的:(给Vue扩展方法)