vue中hookEvent,原來可以這樣監(jiān)聽組件生命周期

1. 內(nèi)部監(jiān)聽生命周期函數(shù)

export default {
  mounted() {
    this.chart = echarts.init(this.$el)
    // 請(qǐng)求數(shù)據(jù),賦值數(shù)據(jù) 等等一系列操作...
    
    // 監(jiān)聽窗口發(fā)生變化,resize組件
    window.addEventListener('resize', this.$_handleResizeChart)
    // 通過hook監(jiān)聽組件銷毀鉤子函數(shù),并取消監(jiān)聽事件
    this.$once('hook:beforeDestroy', () => {
      window.removeEventListener('resize', this.$_handleResizeChart)
    })
  },
  updated() {},
  created() {},
  methods: {
    $_handleResizeChart() {
      // this.chart.resize()
    }
  }
}

總結(jié)

在Vue組件中,可以用過$on,$once去監(jiān)聽所有的生命周期鉤子函數(shù),如監(jiān)聽組件的updated鉤子函數(shù)可以寫成 this.$on('hook:updated', () => {})

2. 外部監(jiān)聽生命周期函數(shù)

今天同事在公司群里問,想在外部監(jiān)聽組件的生命周期函數(shù),有沒有辦法?。?/p>

為什么會(huì)有這樣的需求呢,原來同事用了一個(gè)第三方組件,需要監(jiān)聽第三方組件數(shù)據(jù)的變化,但是組件又沒有提供change事件,同事也沒辦法了,才想出來要去在外部監(jiān)聽組件的updated鉤子函數(shù)。查看了一番資料,發(fā)現(xiàn)Vue支持在外部監(jiān)聽組件的生命周期鉤子函數(shù)。

<template>
  <!--通過@hook:updated監(jiān)聽組件的updated生命鉤子函數(shù)-->
  <!--組件的所有生命周期鉤子都可以通過@hook:鉤子函數(shù)名 來監(jiān)聽觸發(fā)-->
  <custom-select @hook:updated="$_handleSelectUpdated" />
</template>
<script>
import CustomSelect from '../components/custom-select'
export default {
  components: {
    CustomSelect
  },
  methods: {
    $_handleSelectUpdated() {
      console.log('custom-select組件的updated鉤子函數(shù)被觸發(fā)')
    }
  }
}
</script>


開發(fā)全局組件,你可能需要了解一下Vue.extend

開發(fā)loading組件

<template>
  <transition name="custom-loading-fade">
    <!--loading蒙版-->
    <div v-show="visible" class="custom-loading-mask">
      <!--loading中間的圖標(biāo)-->
      <div class="custom-loading-spinner">
        <i class="custom-spinner-icon"></i>
        <!--loading上面顯示的文字-->
        <p class="custom-loading-text">{{ text }}</p>
      </div>
    </div>
  </transition>
</template>
<script>
export default {
  props: {
  // 是否顯示loading
    visible: {
      type: Boolean,
      default: false
    },
    // loading上面的顯示文字
    text: {
      type: String,
      default: ''
    }
  }
}
</script>

開發(fā)出來loading組件之后,如果需要直接使用,就要這樣去用

<template>
  <div class="component-code">
    <!--其他一堆代碼-->
    <custom-loading :visible="visible" text="加載中" />
  </div>
</template>
<script>
export default {
  data() {
    return {
      visible: false
    }
  }
}
</script>

但這樣使用并不能滿足我們的需求

1.可以通過js直接調(diào)用方法來顯示關(guān)閉
2.loading可以將整個(gè)頁面全部遮罩起來

通過Vue.extend將組件轉(zhuǎn)換為全局組件

  1. 改造loading組件,將組件的props改為data
export default {
  data() {
    return {
      text: '',
      visible: false
    }
  }
}

2.通過Vue.extend改造組件

// loading/index.js
import Vue from 'vue'
import LoadingComponent from './loading.vue'

// 通過Vue.extend將組件包裝成一個(gè)子類
const LoadingConstructor = Vue.extend(LoadingComponent)

let loading = undefined

LoadingConstructor.prototype.close = function() {
  // 如果loading 有引用,則去掉引用
  if (loading) {
    loading = undefined
  }
  // 先將組件隱藏
  this.visible = false
  // 延遲300毫秒,等待loading關(guān)閉動(dòng)畫執(zhí)行完之后銷毀組件
  setTimeout(() => {
    // 移除掛載的dom元素
    if (this.$el && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el)
    }
    // 調(diào)用組件的$destroy方法進(jìn)行組件銷毀
    this.$destroy()
  }, 300)
}

const Loading = (options = {}) => {
  // 如果組件已渲染,則返回即可
  if (loading) {
    return loading
  }
  // 要掛載的元素
  const parent = document.body
  // 組件屬性
  const opts = {
    text: '',
    ...options
  }
  // 通過構(gòu)造函數(shù)初始化組件 相當(dāng)于 new Vue()
  const instance = new LoadingConstructor({
    el: document.createElement('div'),
    data: opts
  })
  // 將loading元素掛在到parent上面
  parent.appendChild(instance.$el)
  // 顯示loading
  Vue.nextTick(() => {
    instance.visible = true
  })
  // 將組件實(shí)例賦值給loading
  loading = instance
  return instance
}

export default Loading

  1. 在頁面使用loading
import Loading from './loading/index.js'
export default {
  created() {
    const loading = Loading({ text: '正在加載。。。' })
    // 三秒鐘后關(guān)閉
    setTimeout(() => {
      loading.close()
    }, 3000)
  }
}

通過上面的改造,loading已經(jīng)可以在全局使用了,如果需要像element-ui一樣掛載到Vue.prototype上面,通過this.$loading調(diào)用,還需要改造一下

將組件掛載到Vue.prototype上面

Vue.prototype.$loading = Loading
// 在export之前將Loading方法進(jìn)行綁定
export default Loading

// 在組件內(nèi)使用
this.$loading()
?著作權(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ù)。

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