Vue- 生命周期详解

一、理解

生命周期:从一个组件创建、数据初始化、编译模板、挂载Dom、渲染、更新、销毁。历经如下步骤

beforeCreate->watch->created->computed->beforeMount->mounted->beforeUpdate->updated->beforeDestroy->destroyed

二、生命周期

 生命周期图.png

1、new Vue()

        实例化一个Vue实例。生命周期的钩子函数中的this,会默认指向vue的实例。

2、beforeCreate(){}

        数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化,因此无法访问methods, data, computed等上的方法和数据

3、watch:{}

          后续详细讲解

4、created(){}

        完成了data 数据的初始化,el没有。以及能获取到methods下的方法了, 所以在这里可以开始调用方法进行请求。

5、computed:{}

          后续详细讲解

6、beforeMount(){}

        也就是说实际从created到beforeMount之间,最主要的工作就是将模板或者el转换成render函数。并且我们可以看出一点,就是你不管是用el,还是用template, 或者是用我们最常用的.vue文件(如果是.vue文件,他其实是会先编译成为template),最终他都是会被转换为render函数的。

    所以挂在开始之前被调用,相关的render函数首次被调用(虚拟DOM),实例已完成以下的配置: 编译模板,把data里面的数据和模板生成html,完成了el和data 初始化,注意此时还没有挂在html到页面上

7、mounted(){}

         数据和DOM都完成挂载(即模板完成了渲染),在上一个周期占位的数据把值给渲染进去。可以在这边请求,不过created请求会更好一些。这个周期适合执行初始化需要操作DOM的方法

8、beforeUpdate(){}

        实现原理:当调用时候,我们又重新生成一个新的虚拟dom(Vnode),然后拿这个Vnode和原来的Vnode去做一个diff算,从而更新render函数中的最新数据,再讲更新后的render函数渲染成真实的dom。也就完成了我们的数据更新

        只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候会执行这个周期,如果没有数据改变不执行。

9、updated(){}

            只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的。beforeUpdate和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和容易死循环。

10、beforeDestroy(){}

         这个周期是在组件销毁之前执行,在我项目开发中,觉得这个其实有点类似路由钩子beforeRouterLeave,都是在路由离开的时候执行,只不过beforeDestroy无法阻止路由跳转,但是可以做一些路由离开的时候操作,因为这个周期里面还可以使用data和method。比如一个倒计时组件,如果在路由跳转的时候没有清除,这个定时器还是在的,这时候就可以在这个里面清除计时器。

11、destroyed(){}

        销毁完成后

注意:

mouted和updated的执行,并不会等待所有子组件都被挂载完成后再执行,所以如果你希望所有视图都更新完毕后再做些什么事情,那么你最好在mouted或者updated中加一个$nextTick(),然后把要做的事情放在$netTick()中去做

三、computed和watch

1、watch:数据变化时执行异步或开销较大的操作,可以随时修改状态的变化。主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象。其类似于监听机制+事件机制

2、computed:当页面中有某些数据依赖其他数据进行变动的时候,可以使用计算属性,是基于data中数据进行处理的,data数据变化,他也跟着变化。当data中数据没有发生改变时,我们调用computed中函数n次,只会进行缓存(执行一次)

watch和computed区别:

1.watch擅长处理的场景:一个数据影响多个数据;不支持缓存,数据变,直接会触发相应的操作;watch支持异步,或者在高性能消耗操作上执行。

2.computed擅长处理的场景:一个数据受多个数据影响;支持缓存,只有依赖数据发生改变,才会重新进行计算;不支持异步;

1、watch的普通使用

<template>
  <div id="login">
    <div class="wrapper">
      <template>
        <div class="content">
          <h3>验证watch使用场景</h3>
          密码: <input v-model="nameValue" type="text" /> {{ tip }}
        </div>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      nameValue: "",
      tip: "",
    };
  },
  watch: {
    // 数据变化时执行异步或开销较大的操作
     nameValue(value) { // 普通使用
       this.checkName(value);
     },
  },
  
  methods: {
    checkName(value) {
      const that = this;
      if (value === "admin") {
        that.tip = "12345";
      } else {
        that.tip = "abc123";
      }
    },
  },
};
</script>
<style>
@import "../assets/css/my.css";
</style>

2、watch高级用法

备注:上面的watch方法是当改变值时候,才会触发监听事件,但是我们刚进入页面时候,就触发监听事件,就要用handler()方法

 2.1  handler()

当页面刚进入时,自动绑定watch事件,不需要进行触发

watch: {// 页面加载时,就自动触发此事件
  nameValue:{
    handler(new){
       this.checkName(value);
       this.tip = "正在验证......";
    }
  }
}

 2.2 immediate属性:布尔值

    immediate:true:首次加载、刷新、数据改变都会执行,缺点监听不到对象属性中发生改变。
    immediate:false:只有发生改变才监听

  nameValue: {
      handler(value) {
        this.checkName(value);
        this.tip = "正在验证......";
      },
      immediate: true,
    },

 2.3  deep:true;

     是开启深层次的监听,即所有属性都加上监听器,如果其中一个发生改变了就执行handler函数。

  nameValue: {
      handler(value) {
        this.checkName(value);
        this.tip = "正在验证......";
      },
      immediate: true,
      deep:true
    },

如果想要监听getParm里面某个值的变化,比如监听getParm对象的keyword的值,可以这么写(监听对象里的某个属性要加' '):

watch:{
    'getParam.keyWord':{
      handler(newValue,oldValue){
        //getParam.keyWord改变,执行的函数
        ...
      },
      deep:true
    }
}

3、computed

在computed中,可以定义一些 属性,这些属性,叫做 【计算属性】, 计算属性的本质,就是一个方法,只不过,我们在使用这些计算属性的时候,是把它们的名称直接当作属性来使用的;并不会把计算属性当作方法去调用;
 注意

1、计算属性,在引用的时候,一定不要加 () 去调用,直接把它当作普通属性去使用就好了;
2、只要计算属性,这个function内部,所用到的任何data中的数据发送了变化,就会立即重新计算这个计算属性的值;
3、计算属性的求值结果,会被缓存起来,方便下次直接使用; 如果计算属性方法中,所以来的任何数据,都没有发生过变化,则不会重新对计算属性求值;

<template>
  <div id="login">
    <div class="wrapper">
      <template>
        <div class="content">
          <h3>验证computed使用场景</h3>
          用户名:<span>{{ fullName }}</span>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: "李",
      lastName: "四",
    };
  },
  computed: {
    fullName() {
      return this.firstName + " " + this.lastName;
    },
  },
};
</script>
<style>
@import "../assets/css/my.css";
</style>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

To-strive

你的鼓励是我创作的最大鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值