前端面试题之什么是vue生命周期?vue生命周期详解(案例)

         后边是有案例的,通过案例依次分析Vue生命周期所包含的4大阶段8大钩子函数

1.vue生命周期是什么?

Vue生命周期是指vue实例对象从创建之初到销毁的过程,vue所有功能的实现都是围绕其生命周期进行的,在生命周期的不同阶段调用对应的钩子函数实现组件数据管理和DOM渲染两大重要功能。

2.vue生命周期可以分为八个阶段。

1、创建前(beforeCreate)

对应的钩子函数为beforeCreate。此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

vue实例中的el,data,data中的属性都为undefined (详见案例)

2、创建后(created)

对应的钩子函数为created。在这个阶段vue实例已经创建,仍然不能获取DOM元素。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

el依旧是undefined,而数据已经与data中的属性进行绑定(放在data中属性当值发生改变的同时,视图也会发生变化),在这里可以在渲染前倒数第二次更改数据的机会(最后一次更改是下一个钩子函数),可以在这里做初始数据的获取(详见案例)

3、载入前(beforeMount)

对应的钩子函数是beforeMount,在这一阶段,依然得不到具体的DOM元素,但vue挂载的根节点已经创建,下面vue对DOM的操作将围绕这个根元素继续进行;beforeMount这个阶段是过渡性的,一般一个项目只能用到一两次。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

载入前(完成了data和el数据初始化),但是页面中的内容还是vue中的占位符,data中的message信息没有被挂在到DOM节点中,在这里是渲染前最后一次更改数据的机会了,不会触发其他的钩子函数,可以在这里做初始数据的获取(详见案例)

4、载入后(mounted)

created不能操作DOM节点,mounted可以操作DOM节点

对应的钩子函数是mounted。mounted是平时我们使用最多的函数了,一般我们的异步请求都写在这里。在这个阶段,数据和DOM都已被渲染出来。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

载入后html已经渲染(ajax请求可以放在这个函数中),把vue实例中的data里的message挂载到BOM节点中去

5、更新前(beforeUpdate)

对应的钩子函数是beforeUpdate。在这一阶段,vue遵循数据驱动DOM的原则;beforeUpdate函数在数据更新后虽然没立即更新数据,但是DOM中的数据会改变,这是Vue双向数据绑定的作用。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

更新前状态(view层的数据变化前,不是data中的数据改变前),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树进行对比之后重新渲染(详见效果2

6、更新后(updated)

对应的钩子函数是updated。在这一阶段DOM会和更改过的内容同步。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

数据已经更改完成,dom也重新渲染完成(详见效果2

7、销毁前(beforeDestroy)

对应的钩子函数是beforeDestroy。在上一阶段vue已经成功的通过数据驱动DOM更新,当我们不在需要vue操纵DOM时,就需要销毁Vue,也就是清除vue实例与DOM的关联,调用destroy方法可以销毁当前组件。在销毁前,会触发beforeDestroy钩子函数。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等…’)(详见效果3

8、销毁后(destroyed)

对应的钩子函数是destroyed。在销毁后,会触发destroyed钩子函数。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

销毁后 (Dom元素存在,只是不再受vue控制),卸载watcher,事件监听,子组件(详见效果3

代码:

配置路由:页面重定向为index,跳转到content组件,再从content组件跳转到last组件,完成content组件的一整个生命周期。

import Vue from 'vue'
import Router from 'vue-router'
import Index from  "@/sszq-pages/Index.vue"
import Content from  "@/sszq-pages/Content.vue"
import Last from  "@/sszq-pages/Last.vue"
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      redirect:'/index',
    },
    {
      path: '/index',
      name: 'index',
      component:Index
    },
    {
      path: '/content',
      name: 'content',
      component:Content
    },
    {
      path: '/last',
      name: 'last',
      component:Last
    }
  ]
})

index组件:

<template>
    <div>
      <p>Hello World!</p>
      <router-link to="/content">点击跳转content</router-link>
    </div>
</template>

<script>
import contents from "@/sszq-pages/Content.vue"
export default {
  name: 'index',
  components: {
    contents
  },
  data () {
    return {

    }
  }
}
</script>

content组件:

<template>
    <div>
      <p>{{msg}}</p>
      <button @click="toChange()">更改数据</button>
      <router-link to="/last">销毁此组件,跳转新界面</router-link>
    </div>
</template>
<script>
import Last from "@/sszq-pages/Last.vue"
export default {
  name: 'last',
  components: {
    Last
  },
  data () {
    return {
      msg:'这是初始数据'
    }
  },
  beforeCreate() {
    console.log('this.$el 值为',this.$el,'创建前')
    console.log('this.msg 值为',this.msg,'创建前')
  },
  created() {
    console.log('this.$el 值为',this.$el,'创建后')
    console.log('this.msg 值为',this.msg,'创建后')
  },
  beforeMount() {
    console.log('this.$el 值为',this.$el,'载入前')
    console.log('this.msg 值为',this.msg,'载入前')
  },
  mounted() {
    console.log('this.$el 值为',this.$el,'载入后')
    console.log('this.msg 值为',this.msg,'载入后')
  },
  beforeUpdate() {
    alert('页面数据即将改变。')
    console.log('this.$el 值为',this.$el,'更新前')
    console.log('this.msg 值为',this.msg,'更新前')
    alert('页面数据已经改变。')
  },
  updated() {
    alert('执行更新后。')
    console.log('this.$el 值为',this.$el,'更新后')
    console.log('this.msg 值为',this.msg,'更新后')
  },
  beforeDestroy() {
    console.log('this.$el 值为',this.$el,'销毁前')
    console.log('this.msg 值为',this.msg,'销毁前')
    alert('销毁该组件?')
  },
  destroyed() {
    console.log('this.$el 值为',this.$el,'销毁后')
    console.log('this.msg 值为',this.msg,'销毁后')
  },

  methods:{
    toChange(){
      this.msg='我是新的数据'
    }
  }
}
</script>

Last组件:

<template>
    <div>
      <p>这是last</p>
    </div>
</template>

<script>
export default {
  name: 'Last',
  data () {
    return {

    }
  },
}
</script>

效果1:第一次加载页面会触发 beforeCreate, created, beforeMount, mounted 四个钩子。

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

效果2: (beforeUpdate  updated)

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

效果3:(beforeDestroy destroyed)

前端面试题之什么是vue生命周期?vue生命周期详解(案例)

3.生命周期适用场景

beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也可以在这里调用
mounted : 可以在这里向后端发送请求,获取数据,挂载元素,获取到DOM节点。
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom

4.对vue生命周期的理解

创建前/后:在beforeCreated阶段,vue实例的挂载完el还没有。
载入前/后:在beforeMount阶段,vue实例的$el和data都已经初始化,但还是挂载之前为虚拟的dom节点,案例中的data.msg还未替换。在mounted阶段,vue实例挂载完成,data.msg成功渲染。
更新前/后:当data变化时,会触发beforeUpdate和updated方法。
销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,DOM元素存在,只是不再受vue的控制。

后续会继续完善~~

上一篇:动态规划法(八)最大子数组问题(maximum subarray problem)


下一篇:JQ规范解析html字符串为DOM