您好,登錄后才能下訂單哦!
這篇文章主要講解了“vue2中的@hook怎么使用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vue2中的@hook怎么使用”吧!
@hook是什么?用來監聽組件生命周期的回調函數。
這和生命周期函數mounted,created,updated有什么區別?
區別1:@hook 會在對應的生命周期函數執行后執行。
區別2:@hook 可以在父組件監聽子組件的生命周期運行情況。
從這段vue源代碼中我們能看到hook的部分調用邏輯,vm.$emit('hook:' + hook)
其實就是在調用我們寫的@hook:mounted="xxx"
,@hook這個api卻沒有在官方文檔中出現,所以鮮有人知道它的存在和用法。
通常寫法
export default { components: {}, data: () => { return { name: 'dx', }; }, created() { console.log('created') }, beforeMount() { console.log('beforeMount') }, mounted() { console.log(this.name); // 每一個小時刷新一次頁面 setInterval(() => { location.reload() }, 60 * 60 * 1000); }, }
@hook的用法
export default { components: {}, data: () => { return { name: 'dx', }; }, created() { console.log('created'); this.$on('hook:beforeMount', () => { console.log('beforeMount'); }); this.$on('hook:mounted', () => { console.log(this.name); // this 就是組件實例自己 // 每一個小時刷新一次頁面 setInterval(() => { location.reload(); }, 60 * 60 * 1000); }); }, };
注意
按照生命周期執行的先后周期,我們只能mounted生命周期里,寫這之后的生命周期,而不能寫hook:beforeMount
this.$on
第二個回調函數的this
指的是當前組件實例本身,無論這個回調函數是否是箭頭函數。
通常寫法
// 父組件 <Children @buttonRender="ButtonRender"/> export default { name: 'Parents', components: { Children }, data: () => { return { name: 'dx', }; }, methods: { ButtonRender() { console.log('渲染完成') } } } // 子組件 export default { name: 'Children', components: {}, data: () => {}, methods: {}, mounted() { this.$emit('buttonRender') } }
@hook的寫法
<Children @hook:mounted="ButtonRender"/> export default { name: 'Parents', components: { Children }, data: () => { return { name: 'dx', }; }, methods: { ButtonRender() { console.log('渲染完成') } } }
注意
@hook的寫法可以不需要在子組件里面編寫其它代碼
從vue源碼中可以發現 vm.$emit('hook:' + hook) 這里雖然調用了hook但沒有返回參數,也就是說,上面代碼中ButtonRender沒有默認參數。
同樣承接著2來說,由于ButtonRender沒有默認參數,所以我們無法在ButtonRender函數中獲取子組件Children的實例。
為了解決3的問題,我嘗試著想到一種方法,利用ref獲取子組件的實例,將子組件的實例拿到父組件的this中。ButtonRender中的this就是父組件實例,和尋常methods中的函數沒區別。
<Children ref="child1" @hook:mounted="ButtonRender"/> export default { name: 'Parents', components: { Children }, data: () => { return { name: 'dx' }; }, mounted() {}, methods: { ButtonRender() { console.log(this.$refs.child1) // this.$refs.child1就是子組件Children的實例了 console.log('渲染完成') } } };
但是,我們都知道,vue ref的綁定都是掛載完成之后,所以這個方法也只能用在@hook:mounted
、@hook:updated
等mounted之后執行的生命周期中,而不能用在 比如@hook:beforeMount
中。
許多時候,我們不得不在不同的生命周期中執行某些邏輯,并且這些邏輯會用到一些通用的變量,這些通用變量按照之前的方式,我們不得不存在data中。
<script> export default { data() { return { timer:null } } mounted () { this.timer = setInterval(() => { // todo }, 1000); } beforeDestroy () { clearInterval(this.timer) } } </script>
優化后,就不存在這個問題,是不是很好用。
<script> export default { mounted () { const timer = setInterval(() => { // todo }, 1000); this.$once('hook:beforeDestroy', function () { clearInterval(timer) }) } } </script>
如果屬于同一業務的邏輯要在不同的生命周期中執行,下面這樣會更利于閱讀和維護。
export default { created() { this.$on('hook:mounted', () => { 掛載時執行一些業務A相關邏輯 }) this.$on('hook:updated', () => { 掛載時執行一些業務A相關邏輯 }) this.$once('hook:beforeDestroy', () => { 掛載時執行一些業務A相關邏輯 }) } }
想要監聽別人封裝好的組件(第三方組件)的生命周期,你不可能去第三方子組件的生命周期中寫代碼。
比如 element-ui 的button組件,在子組件渲染完成后,我想做某些邏輯變更。
<el-button type="primary" @hook:mounted="ButtonRender" :disabled="disabled">{{name}}</el-button> export default { name: 'Parents', data: () => { return { name: 'dx', disabled: true }; }, methods: { ButtonRender() { this.disabled = false this.name = 'yx' } } }
父beforeCreate
父 hook:beforeCreate
父created
父 hook:created
父beforeMount
父 hook:beforeMount
子beforeCreate
子hook:beforeCreate
子created
子hook:created
子beforeMount
子hook:beforeMount
子mounted
子hook:mounted
父mounted
父 hook:mounted
父beforeUpdate
父hook:beforeUpdate
子beforeUpdate
子hook:beforeUpdate
子updated
子hook:updated
父updated
父hook:updated
父beforeDestroy
父hook:beforeDestroy
子beforeDestroy
子hook:beforeDestroy
子destroyed
子hook:destroyed
父destroyed
父hook:destroyed
以上內容涉及到vue父子組件生命周期執行順序的知識,但對于@hook:xxx來說,在xxx執行后就會立即執行@hook:xxx
感謝各位的閱讀,以上就是“vue2中的@hook怎么使用”的內容了,經過本文的學習后,相信大家對vue2中的@hook怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。