Vue2 第四天學習(Vue的生命週期)

龍恩0707發表於2017-05-06

閱讀目錄

1.理解VUE---混合

在瞭解Vue生命週期之前,我們先來學習Vue中的混合吧;

為什麼需要使用混合?
  假如當我們開發時候,a.js和b.js都有公用的程式碼的時候,我們可以把他們抽取出來,在a.js或b.js的需要的時候可以引用進來即可,這可以簡單的理解為混合。
  混合物件可以包含任意元件選項,所有混合物件的選項將被混入該元件本身的選項。什麼意思呢?可以簡單的理解為該元件引入該混合物件的時候,該元件擁有該混合物件的所有屬性和方法。
看下如下demo程式碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
  </head>
  <body>
    <div id='app'> 
    </div> 
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    // 定義一個混合物件
    var myMixin = {
      template: '<div>hello world</div>',
      methods: {
        hello: function() {
          console.log('hello');
        },
        say: function() {
          console.log('I am longen');
        }
      }
    };
    // 定義一個元件 使用上面的混合物件
    var Component = Vue.extend({
      mixins: [myMixin],
      methods: {
        list: function() {
          console.log('lists');
        },
        say: function() {
          console.log('I am kongzhi');
        }
      }
    });
    // 例項化
    var Vm = new Component({
      el: '#app'
    });
    Vm.hello(); // 列印出 hello
    Vm.list();  // 列印 lists
    Vm.say();   // 列印 I am kongzhi
  </script>
</html>

上面程式碼可以看到 當例項化物件本身和混合物件有相同的函式名的時候,會先呼叫自身的函式,如果自身的函式不存在,才會
尋找混合物件的函式名。

2.Vue例項化選項

在例項化vue時,需要傳入一個選項物件,它可以包含資料(data), 模板(template), 掛載元素(el), 方法(methods), 生命週期構造選項等。
2-1 data
Vue例項的資料都儲存在data物件中,Vue將會遞迴將data的屬性轉換為getter/setter, 讓data資料能夠響應變化。
比如如下程式碼:

var data = {
  a: 1
};
var vm = new Vue({
 data: data
});
console.log(vm);
console.log(vm.a === data.a); // true
console.log(vm.$data === data); // true

2-2 computed
該屬性可以理解為計算屬性,getter 和 setter的this上下文自動的繫結vue的例項。如下程式碼:

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  computed: {
    reversedMessage: function() {
      return this.message.split('').reverse().join('')
    }
  }
});
console.log(vm.reversedMessage);  // olleH  

切記:呼叫屬性 只能 vm.reversedMessage, 因為不是呼叫方法,後面不能加小括號;且後面的function不要使用箭頭函式代替,因為this一般都指向vue的例項。

2-3 methods
從字面量理解可以認為 是vue的所有方法寫在該物件中,可以直接通過vue例項訪問這些方法。方法中this指向vue的例項。如下程式碼:

var vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  methods: {
    reversedMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
});
console.log(vm.reversedMessage()) // -> 'olleH' 

從上面的 methods 和 computed看 他們兩者都可以做同樣的事情,那麼他們的區別是?computed是計算屬性的,methods是計算方法的,最主要的區別是 computed計算屬性可以對
屬性進行快取的,計算屬性只有當該屬性發生變化的時候才會重新計算值,只要值沒有改變,它是不會重新渲染的,但是methods方法不同,每次呼叫該方法的時候,都會重新執行的。

2-4 watch
可以理解為 觀察某個值發生變化的回撥函式。值也可以是方法名,或者包含選項的物件,Vue例項將會在例項化時呼叫$watch(),遍歷watch物件的每一個屬性。
如下程式碼:

var vm = new Vue({
  data: {
    a: 11,
    b: 22,
    c: 33
  },
  watch: {
    // 監控a變數變化的時候,會自動執行該函式。
    a: function(newVal, oldVal) {
      console.log(newVal);  // 列印 12
      console.log(oldVal);  // 列印 11
    }
  }
});
vm.a = 12; // 改變a的值,會自動呼叫watch物件中的a函式,返回新值 和 舊值。

3.Vue例項化的生命週期

例項化生命週期 從開始建立,初始化資料,編譯模板,掛載Dom->渲染, 更新->重新渲染,銷燬等。

beforeCreate: function() {}  // 在例項初始化之後, 資料觀測 和 event/watcher 事件配置之前被呼叫。
created: function() {}       // 例項已經建立完成之後被呼叫。例項已完成如: 資料觀測,屬性和方法的計算,watch/event事件回撥。
beforeMount: function() {}   // 在掛載開始之前被呼叫, 該函式在伺服器端渲染期間不會被呼叫。
mounted: function() {}       // el被新建立的 vm.$el替換,並掛載到例項上去之後呼叫該函式,在該函式內可以獲取元素。
render: function() {}        // 頁面被渲染時會呼叫該函式。該函式在mounted之前會被呼叫。
beforeUpdate: function(){}   // 資料更新時呼叫,發生在虛擬Dom重新渲染之前。該函式在伺服器端渲染期間不會被呼叫。
updated: function() {}       // 由於資料更改導致虛擬DOM重新被渲染會呼叫。在被渲染後呼叫該函式。可以或許新的dom元素。該函式在伺服器端渲染期間不會被呼叫。
activated: function() {}     // keep-alive元件啟用時呼叫 該函式在伺服器端渲染期間不會被呼叫。
deactivated: function(){}    // keep-alive 元件停用時被呼叫。該函式在伺服器端渲染期間不會被呼叫。
beforeDestroy: function(){}  // 例項銷燬之前被呼叫,例項仍然完全可用 該函式在伺服器端渲染期間不會被呼叫。
destroyed: function() {}     // Vue 例項銷燬後呼叫,呼叫後,Vue例項所有東西都會被解繫結,所有的事件監聽器會被移除,所有的例項被銷燬。

下面看看程式碼如下:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
  </head>
  <body>
    <div id='app'>
      <p> {{ number }} </p>
      <input type='text' v-model='number' />
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        number: 1
      },
      beforeCreate: function() {
        console.log('beforeCreate', this.number);
      },
      created: function() {
        console.log('created', this.number);
      },
      beforeMount: function() {
        console.log('beforeMount:', this.number)
      },
      mouted: function() {
        console.log('mouted', this.number);
      },
      beforeUpdate: function() {
        console.log('beforeUpdate', this.number);
      },
      updated: function() {
        console.log('updated', this.number);
      },
      beforeDestroy: function() {
        console.log('銷燬前.....');
      },
      destroyed: function() {
        console.log('已銷燬.....');
      }
    });
    Vue.nextTick(function () {
      // DOM 更新了
      console.log(1111);  // 列印出 1111
    })
  </script>
</html>

我們在瀏覽器控制檯看到,第一次頁面載入後,列印資訊如下:

beforeCreate undefined
created 1
beforeMount: 1
1111

從上面可以看到,頁面第一次載入後,觸發了 beforeCreate,created,beforeMount等生命週期函式,當然 mouted 生命週期在載入完後dom操作也會被觸發的。
beforeCreate 在例項建立之前 是獲取不到值的,上面頁面載入完成後,可以看出值為undefined;
當我們在控制檯 console.log('mounted: ', document.getElementsByTagName('p')[0]) DOM 渲染在 mounted 中已經完成。
我們接著在input輸入框 在輸入一個1字,控制檯列印出如下資訊:
beforeUpdate 11
updated 11

可以看到當內容被更新的時候 呼叫了 beforeUpdate 和 updated 等生命週期函式。
當我繼續在控制檯中 呼叫如下銷燬方法:vm.$destroy() 後,在控制檯會列印如下資訊:
銷燬前.....
已銷燬.....
說明這時候會自動呼叫了 beforeDestroy 和 destroyed 等生命週期函式。為此整個生命週期過程就是這樣的。

Vue.nextTick([callback, context]): 在DOM更新迴圈結束之後執行的延遲迴調函式,在修改資料之後立即使用這個方法,獲取更新後的DOM元素。

Vue.nextTick(function () {
  // DOM 更新了
  console.log(1111);  // 列印出 1111
})

相關文章