vue生命周期

vue生命周期与钩子函数

组件的创建到销毁的一系列过程叫做组件的生命周期。

先来一张Vue官网的图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HRGwMJpP-1585113315704)(lifecycle-1585098160285.png)]

生命周期大致分为三个阶段:初始化、运行中、销毁


初始化阶段

beforeCreate

created

beforeMount

mounted

beforeCreate

组件通过new Vue() 创建出来之后会初始化事件和生命周期后 立即执行

数据还没有挂载到,无法访问到数据和真实的dom

一般不做操作

beforeCreate(){
  //undefined null
  console.log(this.msg,document.getElementById("title"))
},

created

数据已被挂载,真实 dom 还没被渲染出来,执行该函数

可以访问到数据,无法访问页面中的真实 dom 元素

在这里同步更改数据 不会触发 运行中的 updated 函数

一般可以在这里做初始数据的获取。 做异步ajax,绑定初始化事件

created(){
  // this.msg = 222222222222222	可以更改数据,不触发updated函数
  //1 null
  console.log(this.msg,document.getElementById("title"))
},

beforeMount

找实例或者组件对应的模板,编译模板为虚拟dom放入到 render 函数中准备渲染,然后执行该函数

用法大致与 created 一样,可以做ajax与初始化事件的绑定操作

beforeMount(){
 	//1 null
  console.log(this.msg,document.getElementById("title"))
},

mounted

开始执行render函数渲染页面,渲染出真实dom了,然后执行该函数

可以访问到数据 和 页面中的真实 dom 元素

可以用来做一些实例化的相关操作 ===> 拖拽

render(){ 
  console.log("render.....")
}

执行以上函数后可发现,页面元素不被渲染出来,说明该函数把组件内部的 render 函数覆盖了,证明渲染页面是通过 render 函数执行

mounted(){
  //1 <h1 id="title"> hello </h1>
  console.log(this.msg,document.getElementById("title"))
},

运行阶段

beforeUpdate

updated

beforeUpdate

dom 挂载完毕了,然后再去当数据 发生变化 的时候,立即执行该函数

该函数执行后,会进行重新构建虚拟 dom,通过 diff 算法与上一次虚拟 dom 进行比较后重新渲染

一般不做什么事儿

updated

数据更新完毕,dom也重新 render 完成,执行该函数

可以操作更新后的dom


销毁阶段

beforeDestroy

destroyed

beforeDestroy

调用 $destroy 方法后,立即执行该函数

一般做一些善后工作,例如清除计时器、清除非指令绑定的事件等等

destroyed

销毁完毕,只剩下dom空壳,没有任何事件的绑定与数据的双向绑定,所有的子实例也都被销毁

做善后工作也可以


小案例

为了加深印象,可以结合生命周期,完成一个轮播图的小案例

本案例引用 vue框架、swiper插件、vue-resource插件实现

引入需要的插件

<link rel="stylesheet" href="../base/swiper.min.css" />
<script src="../base/swiper.min.js"></script>
<script src="../base/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.min.js"></script>

页面标签如下:

<div id="app">
  <my-banner></my-banner>
</div>
<template id="my-banner">
  <div class="swiper-container">
    <div class="swiper-wrapper">
      <div class="swiper-slide" v-for="banner in banners" :key="banner.id">
        <img width="100%" :src="banner.image" alt="" />
      </div>
    </div>
  </div>

js代码如下:

Vue.component("my-banner", {
  template: "#my-banner",
  data() {
    return {
      banners: []
    };
  },
  created() {
    //发送请求获取数据
    this.$http.get("./banners.json").then(res => {
      console.log(res.data.bannerList);
      this.banners = res.data.bannerList;

      this.mySwiper = new Swiper(".swiper-container", {
        //实例化swiper对象
        loop: true, // 循环模式选项
        autoplay: {
          //自动轮播
          delay: 1000
        }
      });
    });
  }
});

new Vue({
  el: "#app"
});

本以为以上代码就可以了,异步获取到数据再初始化swiper对象,但是结果却出问题了,划不动轮播图,也没有自动轮播

原因是什么呢?

结合之前讲过的生命周期钩子函数,豁然开朗,created函数只是挂载数据的,真实的 dom 并没有被渲染出来,所以自然就初始化失败了

怎么解决:

那么将初始化函数放到 mounted 函数里面可以吗?答案是否定的,因为发送请求是异步操作,所以一开始数据为空的时候直接就执行到 mounted 函数,直接开始初始化,之然会失败

所以我们应该将初始化函数放到 updated 函数中,
这样,当请求数据回来的时候,会改变原数据,修改完成,并且与上一次虚拟 dom 进行对比,更新渲染到视图完成后,就会触发 updated 函数,
这时,再进行 swiper 的实例化/初始化就没问题了。

所以,js代码修改为:

Vue.component("my-banner", {
  template: "#my-banner",
  data() {
    return {
      banners: []
    };
  },
  created() {
    //发送请求获取数据
    this.$http.get("./banners.json").then(res => {
      console.log(res.data.bannerList);
      this.banners = res.data.bannerList;
    });
  },
  updated() {
    this.mySwiper = new Swiper(".swiper-container", {
      //实例化swiper对象
      loop: true, // 循环模式选项
      autoplay: {
        //自动轮播
        delay: 1000
      }
    });
  }
});

new Vue({
  el: "#app"
});

这样,就可以简单的实现一个轮播图实例了~

以上就是本人的学习总结,如有不对,欢迎指出~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值