对于实现页面逻辑交互等效果,咱们必须知晓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(); }); });
至此这个问题才算比较满意的解决