对vue生命周期/钩子函数详解

对于实现页面逻辑交互等效果,咱们必须知晓vue的生命周期,才能愉快的玩耍,知道咱们写的东西应该挂载到哪里,vue官方给出的api讲解的那叫一个简单啊,以下:vue

全部的生命周期钩子自动绑定this上下文到实例中,所以你能够访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法(例如created: () => this.fetchTodos())。这是由于箭头函数绑定了父上下文,所以this与你期待的 Vue 实例不一样,this.fetchTodos的行为未定义。vue-router

下面附加一张生命周期图示api

 

 

  生命周期

beforeCreate   初始化以前
created  建立完成
beforeMount   挂载更新前
mounted   被建立
beforeUpdat   数据更新前
updated   被更新后
beforeDestroy   销毁以前
destroyed   销毁以后dom

 

 

详解:

  1. beforeCreate
    官方说明:在实例初始化以后,数据观测(data observer) 和 event/watcher 事件配置以前被调用。
    解释:这个时期,this变量还不能使用,在data下的数据,和methods下的方法,watcher中的事件都不能得到到;异步

    beforeCreate() {
       console.log(this.page); // undefined
       console.log{this.showPage); // undefined
     },
     data() {
       return {
         page: 123
       }
     },
     methods: {
       showPage() {
         console.log(this.page);
       }
     }
  2. created
    官方说明:实例已经建立完成以后被调用。在这一步,实例已完成如下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
    解释说明: 这个时候能够操做vue实例中的数据和各类方法,可是还不能对"dom"节点进行操做;函数

    created() {
       console.log(this.page); // 123
       console.log{this.showPage); // ...
       $('select').select2(); // jQuery插件须要操做相关dom,不会起做用
     },
     data() {
       return {
         page: 123
       }
     },
     methods: {
       showPage() {
         console.log(this.page);
       }
     }
  3. beforeMounte
    官方说明:在挂载开始以前被调用:相关的 render 函数首次被调用。fetch

  4. mounted
    官方说明:el 被新建立的 vm.$el 替换,并挂载到实例上去以后调用该钩子。若是root实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
    解释说明:挂载完毕,这时dom节点被渲染到文档内,一些须要dom的操做在此时才能正常进行this

    mounted() {
       $('select').select2(); // jQuery插件能够正常使用
     },

这时初始化插件没有问题,插件能正常运行,可是这并不表明万事大吉;下面思考一个问题:url

select2
select2

图中的selectoption都是经过异步请求获得的,而后经过v-for渲染进去,到此一切看起来很正常。还有一个需求是当页面刷新后要保留上次一查询的条件。我经过vue-router来给select指定一个默认选项;spa

<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在请求成功以前执行,那将很遗憾——默认选项会设置失败

option有默认效果的是130,select中的值仍是保持所有
option有默认效果的是130,select中的值仍是保持所有

何时执行$('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();
    });
  });

至此这个问题才算比较满意的解决

相关文章
相关标签/搜索