給Vue擴(kuò)展方法

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

vue生命周期

給vue增加一個(gè)擴(kuò)展函數(shù)

  • Vue合并策略
    在Vue中使用mixins時(shí)會(huì)發(fā)現(xiàn), data,props,methods是同名屬性覆蓋合并。生命周期函數(shù)是合并調(diào)用。
    這個(gè)原理就是 “合并策略” 導(dǎo)致的。
    在Vue中,提供了一個(gè)api, Vue.config.optionMergeStrategies,可以通過(guò)這個(gè)api去自定義選項(xiàng)的合并策略。
  • 我們可以利用optionMergeStrategies 這個(gè)屬性來(lái)給 Vue實(shí)例增加一個(gè)擴(kuò)展函數(shù)。
import Vue from 'vue'

// 通知所有組件頁(yè)面狀態(tài)發(fā)生了變化
const notifyVisibilityChange = (lifeCycleName, vm) => {
  // 生命周期函數(shù)會(huì)存在$options中,通過(guò)$options[lifeCycleName]獲取生命周期
  const lifeCycles = vm.$options[lifeCycleName]
  // 因?yàn)槭褂昧薱reated的合并策略,所以是一個(gè)數(shù)組
  if (lifeCycles && lifeCycles.length) {
    // 遍歷 lifeCycleName對(duì)應(yīng)的生命周期函數(shù)列表,依次執(zhí)行
    lifeCycles.forEach(lifecycle => {
      lifecycle.call(vm)
    })
  }
  // 遍歷所有的子組件,然后依次遞歸執(zhí)行
  if (vm.$children && vm.$children.length) {
    vm.$children.forEach(child => {
      notifyVisibilityChange(lifeCycleName, child)
    })
  }
}

/**
 * 添加生命周期鉤子函數(shù)
 * @param {*} rootVm vue 根實(shí)例,在頁(yè)面顯示隱藏時(shí)候,通過(guò)root向下通知
 */
export function init() {
  const optionMergeStrategies = Vue.config.optionMergeStrategies
  /*
    定義了兩個(gè)生命周期函數(shù) pageVisible, pageHidden
    為什么要賦值為 optionMergeStrategies.created呢
    這個(gè)相當(dāng)于指定 pageVisible, pageHidden 的合并策略與 created的相同(其他生命周期函數(shù)都一樣)
   */
  optionMergeStrategies.pageVisible = optionMergeStrategies.beforeCreate
  optionMergeStrategies.pageHidden = optionMergeStrategies.created
}

/**
 * 將事件變化綁定到根節(jié)點(diǎn)上面
 * @param {*} rootVm
 */
export function bind(rootVm) {
  window.addEventListener('visibilitychange', () => {
    // 判斷調(diào)用哪個(gè)生命周期函數(shù)
    let lifeCycleName = undefined
    if (document.visibilityState === 'hidden') {
      lifeCycleName = 'pageHidden'
    } else if (document.visibilityState === 'visible') {
      lifeCycleName = 'pageVisible'
    }
    if (lifeCycleName) {
      // 通過(guò)所有組件生命周期發(fā)生變化了
      notifyVisibilityChange(lifeCycleName, rootVm)
    }
  })
}

使用

  1. 在main.js主入口文件引入
import { init, bind } from './utils/custom-life-cycle'

// 初始化生命周期函數(shù), 必須在Vue實(shí)例化之前確定合并策略
init()

const vm = new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

// 將rootVm 綁定到生命周期函數(shù)監(jiān)聽(tīng)里面
bind(vm)
  1. 在需要的地方監(jiān)聽(tīng)生命周期函數(shù)
export default {
  pageVisible() {
    console.log('頁(yè)面顯示出來(lái)了')
  },
  pageHidden() {
    console.log('頁(yè)面隱藏了')
  }
}

理解

這種方式不僅可以作用在跟實(shí)例上,也可以作用于某個(gè)頁(yè)面。微信小程序的 onShow();onHidden() 實(shí)現(xiàn)也類似于這樣吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官方文檔解說(shuō) 元素作為承載分發(fā)內(nèi)容的出口,在我的理解就是slot元素就是一個(gè)預(yù)留占位坑,我們可以通過(guò)在子組件中設(shè)...
    木子方是個(gè)小太陽(yáng)閱讀 2,319評(píng)論 0 2
  • 插槽的作用:個(gè)人理解,如果子組件需要顯示的東西不是自己的,而是由父組件傳遞進(jìn)來(lái)的則使用slot,父組件可以使用插槽...
    七幺七閱讀 616評(píng)論 0 0
  • <slot> 元素作為承載分發(fā)內(nèi)容的出口,可以實(shí)現(xiàn)組件的復(fù)用。 簡(jiǎn)單的說(shuō)就是《定制模板》 一個(gè)template由多...
    Mr無(wú)愧于心閱讀 6,687評(píng)論 1 0
  • 1.匿名插槽 不指定名字 2.具名插槽(name屬性是必填) 3.作用域插槽 (可以傳遞數(shù)據(jù)) 父組件: 子組件:
    MaJiT閱讀 218評(píng)論 0 0
  • 這里是內(nèi)容 對(duì)應(yīng)著 這里是默認(rèn)插槽 具名插槽?當(dāng)然是有名字的插槽啦。 使用slot對(duì)應(yīng) 標(biāo)簽中的name...
    取個(gè)帥氣的名字真好閱讀 252評(píng)論 0 0

友情鏈接更多精彩內(nèi)容