文章目录
前言
- vue是一套用于构建用户界面的渐进式框架,现已成为 github 上 star 数量最多的前端框架,是三大主流框架之一。
- 由于 vue 是渐进式框架,帮助我们减少不必要的 dom 操作,提高开发效率。使广大前端开发者只需要关注业务逻辑,不再关心 dom 如何渲染。
- 最主流的前端框架之一,你真的了解吗?它的各个命周期都做了什么?下文揭晓。
生命周期钩子
每个 vue 实例都经过一系列初始化步骤,从创建时设置数据到编译模板,将实例装载到 DOM,最后在数据更改期间更新DOM,整个过程被称为 Vue 实例的声明周期。
官网的生命周期流程图:
关于每个钩子函数里组件的状态实例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue的生命周期</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h3>{{info}}</h3>
<button v-on:click='updateInfo'>修改数据</button>
<button v-on:click='destoryComponent'>销毁组件</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
info: 'Vue的生命周期'
},
beforeCreate: function(){
console.log("beforeCreated-组件创建前");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
},
created: function(){
console.log("created-组件创建完毕");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
beforeMount: function(){
console.log("beforeMounted-组件挂载前");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
mounted: function(){
console.log("mounted-组件挂载完毕");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
beforeUpdate: function(){
console.log("beforeUpdate-组件更新前");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
updated: function(){
console.log("updated-组件更新完毕");
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
beforeDestroy: function(){
console.log("beforeDestory-组件销毁前");
//在组件销毁前尝试修改data中的数据
this.info="组件销毁前";
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
destroyed: function(){
console.log("destoryed-组件销毁完毕");
//在组件销毁完毕后尝试修改data中的数据
this.info="组件已销毁";
console.log("el:");
console.log(this.$el);
console.log("data:");
console.log(this.$data);
console.log("info:");
console.log(this.$data.info);
},
methods: {
updateInfo: function(){
// 修改data数据
this.info = '我发生变化了'
},
destoryComponent: function(){
//手动调用销毁组件
this.$destroy();
}
}
});
</script>
</body>
</html>
创建Vue实例
- Vue项目都是通过组件化进行实现的,一个页面通过若干组件组成,构成一个组件树。
- 每个组件都通过一个 Vue 实例来管理。
- 通过 new Vue() 创建实例,实例创建了一个vue 实例的空壳,初始化生命周期和事件
初始化阶段–beforeCreate
这是在 Vue.js 中调用的第一个生命周期钩子,它在vue实例初始化之后,组件创建前被调用。
打印结果:
组件创建前,组件需要挂载的DOM元素el和组件的数据data都未被创建。
从源码中来看看 vue 都做了什么?源码地址
vm._self = vm
initLifecycle(vm) //初始化生命周期,主要做一些属性初始化
initEvents(vm) //初始化事件,初始化父元素给子节点绑定的一些事件
initRender(vm) //初始化 render 函数
callHook(vm, 'beforeCreate')
Tips:在 beforeCreate 中不要去修改 data 中赋值的数据,最早也要在 create 中去做。
初始化阶段–created
- 实例创建完成,完成数据的初始化
- 可访问 data computed watch methods 上的方法和数据
- 不能访问 el,为 undefined
打印结果:
组件创建完毕,组件的数据已经创建成功,但是DOM元素el还没被创建。
挂载阶段–beforeMount
- 页面中的内容还是 vue 的占位符,$el 属性已存在,是虚拟DOM,只是数据未挂载到模板中
打印结果:
组件挂载前,DOM元素已经被创建,只是data中的数据还没有应用到DOM元素上。
挂载阶段–mounted
- 完成创建vm
- 完成 el 双向绑定,完成挂载和DOM渲染,可以在这个阶段对DOM进行操作
打印结果:
组件挂载完毕后,data中的数据已经成功应用到DOM元素上,此时,挂载阶段已经结束。
更新状态–beforeUpdate
- 组件更新前,data数据已经更新,组件挂载的DOM元素的内容也已经同步更新。
- 只有 view 上的数据变化才会触发 beforeUpdate 和 update ,仅属于data 中的数据改变是并不能触发的。
打印结果:
更新状态–updated
- 数据更新完成,dom 也已经 render 完成(render 可以完成渲染操作,是渲染函数)
- 不要在此函数中操作数据,会陷入死循环的。
- 大多数情况下应避免在此期间更新状态,如有相应状态要改变,通常最好使用 computed 和 watch 取而代之。
打印结果:
组件更新完毕后,data数据已经更新,组件挂载的DOM元素的内容也已经同步更新。
实例销毁阶段–beforeDestory
打印结果:
组件销毁前,组件已经不再受vue管理,我们可以继续更新数据,但是模板已经不再更新。
实例销毁阶段–destoryed
打印结果:
- 组件销毁完毕,vue实例指示的所有东西会解除,所有的事件监听也会被移除,所有子实例也会被销毁。
- 执行 destory() 方法后,对 data 的改变不会再触发周期函数,此时 vue 实例已经解除了事件监听以及和 dom 的绑定,但 dom 结构依然存在。
最后
以上为本人学习Vue 生命周期的总结,如有错误,望指正,不胜感激!