對於實現頁面邏輯交互等效果,咱們必須知曉vue的生命週期,才能愉快的玩耍,知道咱們寫的東西應該掛載到哪裏,vue官方給出的api講解的那叫一個簡單啊,以下:javascript
全部的生命週期鉤子自動綁定this上下文到實例中,所以你能夠訪問數據,對屬性和方法進行運算。這意味着你不能使用箭頭函數來定義一個生命週期方法(例如created: () => this.fetchTodos())。這是由於箭頭函數綁定了父上下文,所以this與你期待的 Vue 實例不一樣,this.fetchTodos的行爲未定義。html
下面附加一張生命週期圖示vue
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta charset="utf-8"> 6 <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js"></script> 7 </head> 8 <body> 9 10 <div id="app"> 11 <p>{{ message }}</p> 12 </div> 13 14 <script type="text/javascript"> 15 var app = new Vue({ 16 el: '#app', 17 data: { 18 message: "this is a test" 19 }, 20 beforeCreate: function () { 21 console.group('beforeCreate 建立前狀態===============》'); 22 console.log("%c%s", "color:red", "el : " + this.$el); //undefined 23 console.log("%c%s", "color:red", "data : " + this.$data); //undefined 24 console.log("%c%s", "color:red", "message: " + this.message) 25 }, 26 created: function () { 27 console.group('created 建立完畢狀態===============》'); 28 console.log("%c%s", "color:red", "el : " + this.$el); //undefined 29 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 30 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 31 }, 32 beforeMount: function () { 33 console.group('beforeMount 掛載前狀態===============》'); 34 console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化 35 console.log(this.$el); 36 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 37 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 38 }, 39 mounted: function () { 40 console.group('mounted 掛載結束狀態===============》'); 41 console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化 42 console.log(this.$el); 43 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化 44 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化 45 }, 46 beforeUpdate: function () { 47 console.group('beforeUpdate 更新前狀態===============》'); 48 console.log("%c%s", "color:red", "el : " + this.$el); 49 console.log(this.$el); 50 console.log("%c%s", "color:red", "data : " + this.$data); 51 console.log("%c%s", "color:red", "message: " + this.message); 52 }, 53 updated: function () { 54 console.group('updated 更新完成狀態===============》'); 55 console.log("%c%s", "color:red", "el : " + this.$el); 56 console.log(this.$el); 57 console.log("%c%s", "color:red", "data : " + this.$data); 58 console.log("%c%s", "color:red", "message: " + this.message); 59 }, 60 beforeDestroy: function () { 61 console.group('beforeDestroy 銷燬前狀態===============》'); 62 console.log("%c%s", "color:red", "el : " + this.$el); 63 console.log(this.$el); 64 console.log("%c%s", "color:red", "data : " + this.$data); 65 console.log("%c%s", "color:red", "message: " + this.message); 66 }, 67 destroyed: function () { 68 console.group('destroyed 銷燬完成狀態===============》'); 69 console.log("%c%s", "color:red", "el : " + this.$el); 70 console.log(this.$el); 71 console.log("%c%s", "color:red", "data : " + this.$data); 72 console.log("%c%s", "color:red", "message: " + this.message) 73 } 74 }) 75 </script> 76 </body> 77 </html>
beforeCreate
官方說明:在實例初始化以後,數據觀測(data observer) 和 event/watcher 事件配置以前被調用。
解釋:這個時期,this變量還不能使用,在data下的數據,和methods下的方法,watcher中的事件都不能得到到;java
beforeCreate() { console.log(this.page); // undefined console.log{this.showPage); // undefined }, data() { return { page: 123 } }, methods: { showPage() { console.log(this.page); } }
created
官方說明:實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
解釋說明: 這個時候能夠操做vue實例中的數據和各類方法,可是還不能對"dom"節點進行操做;vue-router
created() { console.log(this.page); // 123 console.log{this.showPage); // ... $('select').select2(); // jQuery插件須要操做相關dom,不會起做用 }, data() { return { page: 123 } }, methods: { showPage() { console.log(this.page); } }
beforeMounte
官方說明:在掛載開始以前被調用:相關的 render 函數首次被調用。api
mounted
官方說明:el
被新建立的 vm.$el
替換,並掛載到實例上去以後調用該鉤子。若是root
實例掛載了一個文檔內元素,當 mounted
被調用時 vm.$el
也在文檔內。
解釋說明:掛載完畢,這時dom
節點被渲染到文檔內,一些須要dom
的操做在此時才能正常進行app
mounted() { $('select').select2(); // jQuery插件能夠正常使用 },
這時初始化插件沒有問題,插件能正常運行,可是這並不表明萬事大吉;下面思考一個問題:dom
圖中的select
的option
都是經過異步請求獲得的,而後經過v-for
渲染進去,到此一切看起來很正常。還有一個需求是當頁面刷新後要保留上次一查詢的條件。我經過vue-router
來給select
指定一個默認選項;異步
<template v-for='(item, index) in agentList.name' > <option v-if='item == name' :key='index' selected :value="item">{{item}}</option> <option v-else :key='index' :value="item">{{item}}</option> </template>
那麼問題就來了,option
的得到是一個異步請求,那這個請求完成的時刻和mounted
的順序是什麼?若是mounted
在請求成功以前執行,那將很遺憾——默認選項會設置失敗ide
何時執行$('select').select2()
,是解決這個問題的關鍵。你們確定猜到了,mounted的確是在請求成功以前執行的,因此這時的辦法就是將$('select').select2()
的執行放到請求成功的回調裏執行:
$.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => { const a = this.agentList, d = res.data; a.id = d.orgIds; a.name = d.orgNames; a.city = d.cityMap; $('select').select2(); });
本覺得這樣就完美解決了,可是發現仍是會出現和上圖同樣的效果;如何是好?這時輪到vm.$nextTick登場了:
說明: 將回調延遲到下次 DOM
更新循環以後執行。在修改數據以後當即使用它,而後等待 DOM
更新。
官方示例代碼:
new Vue({ // ... methods: { // ... example: function () { // 修改數據 this.message = 'changed' // DOM 尚未更新 this.$nextTick(function () { // DOM 如今更新了 // `this` 綁定到當前實例 this.doSomethingElse() }) } } })
因此個人解決辦法以下:
$.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => { const a = this.agentList, d = res.data; a.id = d.orgIds; a.name = d.orgNames; a.city = d.cityMap; this.$nextTick(() => { $('select').select2(); }); });
至此這個問題纔算比較滿意的解決