vue生命周期的理解

Vue组件生命周期


       一个组件从创建到销毁的过程叫做生命周期,其实每个人都要经历一个从出生到死亡的过程,每个阶段都有需要自己要做的事情;组件也一样,在生命周期的每个阶段也有它自己应该做的事情,所以生命周期也理解透彻,在以后的项目中的每一个效果,都是从生命周期中做的。

       每个Vue实例在被创建时,需要设置数据监听、编译模板、将实例挂载在DOM元素上并实时更新DOM元素,以数据推动视图,同时在这个过程也会运用到生命周期的函数,在生命周期中给自己添加代码的机会。

       首先,先来一张官网上的图

  

     可以看到在vue一整个的生命周期中会有很多钩子函数提供给我们在vue生命周期不同的时刻进行操作, 那么我们来一一详解:

  1、首先先来说下 beforeCreate() 钩子函数:


   beforeCreate(创建前)

   当组件初始化的时候会执行 beforeCreate ,在当前生命周期中,我们是无法访问到data中的属性,以及methods中的方法和其他生命周期方法;

   因为当前生命周期是初始化阶段,因此可以在当前生命周期中加一个loading,等待组件加载完毕以后再移除loading;

    

var vm=new Vue({
        data:{
            msg:10,
},
        methods:{
            handler(){
}, }, beforeCreate(){
      //this 指向 vm实例
console.log(this.handler) // underfined
console.log(this.msg) //underfined }, })

  2、与 beforeCreate()钩子函数相对应的还有 created() 钩子函数:


   created()(创建后)

   当前生命周期可以访问到data中的属性以及methods中的方法;

   当前生命周期执行的时候会将data身上的所有属性遍历添加getter/setter方法;

   当前生命周期执行的时候会将data与methods身上所有的属性和方法遍历到vm的实例身上;

   因为当前生命周期会遍历data身上的属性添加getter/setter,因此可以在当前生命周期函数中进行前后端数据的交互;

  

var vm=new Vue({
el:"#app", data:{ msg:10, }, methods:{ handler(){ }, }, created(){     console.log(this.msg) //10 console.log(this.handler) //显示hadnler这个函数 }, })

       按照生命周期整个流程接下来会判断是否有 el 的配置项,如果没有的情况下可以挂载一个,有的话就继续往下走,会再次判断是否有 template 的配置项,有 template 的配置项 会走编译函数,然后用 render 这个函数去渲染,没有的话就走NO(outerHTML)这个模板,我们现在以上面代码为例,所以走outerHTML:

  3、下面的生命周期是 beforeMount()钩子函数:


  beforeMount()(挂载前)

  当前生命周期是数据和模板还未进行结合,可以在当前生命周期中做数据最后的更改;

  

<body>
    <div id="app">
    <h2>{{msg}}</h2>
</div>

<script>
var vm=new Vue({
el:"#app", data:{ msg:
10, }, methods:{ handler(){   } }, beforeMount(){ //在Vue中尽量不用DOM节点,这样会耗费性能,Vue本身就是数据驱动的 console.log(document.getElementById("#app").innerHTML) // <h2>{{msg}}</h2> 会打印出这个模板 当前数据和模板还未相结合   this.msg=100 //在当前生命周期函数做了更改,在下边的生命周期函数做了做后的渲染 }, mounted(){ }, }) </script> </body>

  4、接下来就是 mounted()钩子函数


  mounted()(挂载后)

  当前生命周期是数据和模板进行相结合,可以在当前生命周期中获取到真实的DOM结构;

  之前说不可以操作DOM结构,在这里我们可以通过虚拟DOM元素去做操作,Vue中提供了一个方法叫做 ref ,通过给元素添加 ref 属性,然后在 mounted()中通过 this.$refs. 属性即可获取。

  我们可以在当前生命周期中做方法的实例化,例如(swiper、echarts...)

  

<body>
    <div id="app">
    <h2 ref="h2">{{msg}}</h2> <!--ref属性里边的h2可以是其他值-->
</div>

<script>
var vm=new Vue({
el:"#app", data:{ msg:
10, }, methods:{ handler(){   } }, beforeMount(){ console.log(document.getElementById("#app").innerHTML); // <h2>{{msg}}</h2> 这个是模板   this.msg="100"; }, mounted(){ console.log(document.getElementById("#app").innerHTML) ; // <h2>100</h2> 这个是真实的DOM结构
console.log(this.$refs.h2) }, }) </script> </body>

  5、当数据更新的时候先会执行 beforeUpdate ():


  beforeUpdate( )  (更新前)

  在当前生命周期是更新数据与模板还未进行结合,可以在当前生命周期中做数据更改;

<body>
    <div id="app">
    <h2 >{{msg}}</h2> 
    <button @click="updateHandler">更新</button>
</div>
<script>
var vm=new Vue({
el:"#app", data:{ msg:
10, }, methods:{ updateHandler(){ this.msg=100;   } }, beforeUpdate(){ //按理来说应该是100,但点击更新后最后输出的值为200; this.msg="200"; }
})
</script>
</body>

  6、数据更新后会后执行 updated ( ) :


  updated()(更新后)

  更新后的数据与模板进行相结合,在当前生命周期中我们可以获取到数据更新后最新的DOM结构;

       注意:beforeUpdate updated 这两个生命周期会多次执行,因此在这两个周期中做逻辑操作的时候要加条件处理,否则会极度浪费性能

<body>
    <div id="app">
    <h2 ref="h2">{{msg}}</h2> <!--ref属性里边的h2可以是其他值-->
</div>

<script>
var vm=new Vue({
el:"#app", data:{ msg:
10, }, methods:{ handler(){   } }, beforeMount(){ console.log(document.getElementById("#app").innerHTML); // <h2>{{msg}}</h2> 这个是模板   this.msg="100"; }, mounted(){ console.log(document.getElementById("#app").innerHTML) ; // <h2>100</h2> 这个是真实的DOM结构 console.log(this.$refs.h2) }, updated(){ console.log(this.$refs.h2) //也可以从这个方式获取到真实的DOM结构 //做一个条件处理 if(!this.swiper){ this.swiper= new Swiper() } }, }) </script> </body>

  7、还有就是   beforeDestroy()


  beforeDestroy(销毁前):

  在当前生命周期中仍然可以获取到真实的DOM结果,因此我们可以在当前做事件的移除、事件的解绑等;

      如果说我们在mounted中做了事件侦听,当组件被销毁时,我们要做一个移除;

  8、最后一个是 destroyed()


  destroy()(销毁后)

  在当前生命周期中我们访问不到真实的DOM结构,以及当前的vm实例化与页面之间的关联也断开了;

<body>
    <div id="app">
    <h2 >{{msg}}</h2> 
    <button onclick="destroyHandler()">更新</button>
</div>
<script>
var vm=new Vue({
el:"#app", data:{ msg:
10, }, methods:{ updateHandler(){ this.msg=100;   } }, destroyed(){ console.log(this.$refs.h2) //获取不到真实的DOM结构 } }) function destroyHandler(){ vm.$destroy() } </script> </body>

 9、当我们每次刷新页面或者跳转页面的时候,都需要请求数据,这样极大的浪费性能,不利于页面的优化,这时候我们就需要使用组件 keep-alive , 来提升性能的优化,

  被 keep-alive 包裹的组件第一次被创建后就会保存在内存当中,不会被经历销毁,下次页面切换时就会从缓存中读取。

  

<keep-alive>
      <router-view></router-view>
</keep-alive> <!-- 只要把要缓存的代码包裹在keep-alive中就可以了 -->

  只要被keep-alive包裹的组件就会增加两个生命周期:A、activated  活跃状态   B、deactivated 缓存状态

   A、activated  钩子函数 

  把需要调转的页面代码在 activated 中就可以实现跳转 

  

activated () {
  console.log("activated调用了");
}
原文地址:https://www.cnblogs.com/BySee1423/p/11259182.html