Vue生命週期 鉤子函數和組件傳值

Vue生命週期 鉤子函數

每一個 Vue 實例在被建立時都要通過一系列的初始化過程——例如,須要設置數據監聽、編譯模板、將實例掛載到 DOM 並在數據變化時更新 DOM 等。vue

同時在這個過程當中也會運行一些叫作生命週期鉤子的函數,這給了用戶在不一樣階段添加本身的代碼的機會。(來源:官方文檔)node

官方生命週期圖示:

生命週期的鉤子函數見下表

鉤子函數 觸發的行爲 在此階段能夠作的事情
beforeCreadted

vue實例的掛載元素$el和數據對象dataajax

 都爲undefined,還未初始化。瀏覽器

加loading事件
created

vue實例的數據對象data有了,$el尚未dom

結束loading、請求數據爲mounted渲染作準備
beforeMount

vue實例的$el和data都初始化了,但仍是虛擬的dom節點,函數

具體的data.filter還未替換。性能

...
mounted vue實例掛載完成,data.filter成功渲染 配合路由鉤子使用
beforeUpdate data更新時觸發 ...
updated data更新時觸發

數據更新時,作一些處理(此處也能夠用測試

watch進行觀測)fetch

beforeDestroy 組件銷燬時觸發 ...
destroyed

組件銷燬時觸發,vue實例解除了事件監聽以及和dom的綁定ui

(無響應了),但DOM節點依舊存在

組件銷燬時進行提示

說明一下: 

beforeCreate:el 和 data 並未初始化 (此方法不經常使用) 

created:完成了 data 數據的初始化,el的初始化未完成。用來發送ajax

beforeMount:(執行此方法時已經完成了 el 和 data 初始化 (已經賦予了對應的值)) 

渲染DOM以前先確認下是否有要編譯的根元素(有無el屬性),有才繼續確認是否具備模板屬性template,若是有模版屬性,則會用template的值替

換掉HTML中的結構,template模版中只能有一個根元素(並且不能是文本); 

mounted:(執行此方法時表明已經掛載結束了) 

把編譯好的數據掛載到DOM元素上,最後渲染成真實的DOM元素;真實DOM已經渲染完成,能夠操做DOM了

beforeUpdate:當頁面依賴的數據更改以後觸發(此時DOM結構尚未從新加載) 

updated:DOM結構從新加載以後觸發

調用vm.$destroy()以後觸發下面兩個事件: 

beforeDestroy:實例銷燬以前調用。在這一步,實例仍然徹底可用。(可在此處清除定時器,清除事件綁定) 

destroyed:Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

destroyed鉤子函數有一點必定要特別注意:在執行destroy方法後,對data的改變不會再觸發周期函數,此時的vue實例已經解除了事件監聽

以及和dom的綁定,可是dom結構依然存在。因此對於實時顯示的通知型組件,在他destroyed以前,咱們必須手動removeChild()刪除該節點;

不然,DOM節點仍是存在,影響瀏覽器性能。

注意:

全部的生命週期鉤子自動綁定this上下文到實例中,所以你能夠訪問數據,對屬性和方法進行運算。這意味着你不能使用箭頭函數來定義一個

生命週期方法(例如created: () => this.fetchTodos())。這是由於箭頭函數綁定了父上下文,所以this與你期待的 Vue 實例不一樣,

this.fetchTodos的行爲未定義。

測試代碼:

export default { data () { return { todos: [], allCounts: 0, filter: 'all', id: 0, states: ['all', 'active', 'completed'] } }, beforeCreate () { console.log('==============' + 'beforeCreated' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, created () { console.log('==============' + 'created' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, beforeMount () { console.log('==============' + 'beforeMount' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, mounted () { console.log('==============' + 'mounted' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, beforeUpdate () { console.log('==============' + 'beforeUpdate' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, updated () { console.log('==============' + 'updated' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, beforeDestroy () { console.log('==============' + 'beforeDestroy' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) }, destroyed () { console.log('==============' + 'destroyed' + '===================') console.log(this.$el) console.log(this.$data) console.log(this.filter) } }

測試結果:

組件傳值

Vue經常使用的三種傳值方式有:

  父傳子

  子傳父

  非父子傳值

引用官網的一句話:父子組件的關係能夠總結爲 prop 向下傳遞,事件向上傳遞。父組件經過 prop 給子組件下發數據,子組件經過事件給父

組件發送消息。

1.父組件向子組件進行傳值

父組件

<template>
  <div> 父組件: <input type="text" v-model="name">
    <br>
    <br>
    <!-- 引入子組件 -->
    <child :inputName="name"></child>
  </div>
</template>
<script> import child from './child' export default { components: { child }, data () { return { name: '' } } } </script>

子組件

<template>
  <div> 子組件: <span>{{inputName}}</span>
  </div>
</template>
<script> export default { // 接受父組件的值
 props: { inputName: String, required: true } } </script>

子組件經過props接收父組件傳回的值

2.子組件向父組件傳值

父組件

 

<template>
  <div> 父組件: <span>{{name}}</span>
    <br>
    <br>
    <!-- 引入子組件 定義一個on的方法監聽子組件的狀態-->
    <child v-on:childByValue="childByValue"></child>
  </div>
</template>
<script> import child from './child' export default { components: { child }, data () { return { name: '' } }, methods: { childByValue: function (childValue) { // childValue就是子組件傳過來的值
        this.name = childValue } } } </script>

 

子組件

<template>
  <div> 子組件: <span>{{childValue}}</span>
    <!-- 定義一個子組件傳值的方法 -->
    <input type="button" value="點擊觸發" @click="childClick">
  </div>
</template>
<script> export default { data () { return { childValue: '我是子組件的數據' } }, methods: { childClick () { // childByValue是在父組件on監聽的方法
        // 第二個參數this.childValue是須要傳的值
        this.$emit('childByValue', this.childValue) } } } </script>

子組件經過事件派發向父組件傳值

3.兄弟組件通訊

經過事件總線的方式實現就是一個空的vue示例只用來綁定方法。

舉個例子:

1 在main.js中全局註冊一個

data:{ eventHub: new Vue() }

2 在組件a裏定義須要傳的參數

self.$root.eventHub.$emit('add',{tabnum:tab.index,yuid:tab.$vnode.key,);

3 在組件b裏取得須要接受的參數

self.$root.eventHub.$on('add',function(data) { self.tabnum = data.tabnum; self.yunid = data.yuid;   } })
相關文章
相關標籤/搜索