Vue 2x 系列之(十八)生命周期

生命周期[函数]🔥🔥🔥

js 不善于处理小数,0.1 + 0.2 不一定等于0.3,当通过js判断一个不断缩小的变量的值是否缩小到0时,可以通过<=0进行判断;如果直接判断===0,可能会出现递减的值取不到0的情况

mounted的执行时期:Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted

初始的真实DOM:第一次解析模板后生成的真实DOM

挂载:第一次将真实DOM放入页面才叫挂载,后面再放入页面就是更新DOM了

生命周期:
	1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
	2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。【这些函数我们可以提前准备好,等着Vue去帮我们调用】
	3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
	4.生命周期函数中的this指向是vm 或 组件实例对象。

注意:

  • 回调函数:函数是我自己定义的,但我自己没有主动调用,但这个函数还是执行了

官网提供的生命周期图示

官网的图示网站:https://v2.cn.vuejs.org/v2/guide/instance.html#生命周期图示

以下为添加了注释的图示:

注:上图中绿色色块代表一个个的环节,红色字体代表一个个生命周期函数,黄色色块代表判断操作

注:上图中有三个生命周期没有体现出来,分别是nextTick、actived、deactived

整个生命周期图示分为挂载流程、更新流程、销毁流程,结合上图进行说明:

挂载流程:

  • Init Events & Liftcycle:制定一些规则,比如定义生命周期函数,各生命周期函数的调用时机;又比如遇到事件修饰符后事件的处理方式;这一步,vm身上还没有vm._data,数据代理,比如vm.n,n是data中的一个配置项,也是没有的

  • beforeCreate【生命周期,指的是创建数据监测和数据代理之前】:此时无法通过vm访问data中的数据【Vue收到的data还没有开始解析,vm身上还没有_data】和methods中的方法

  • Init injection & reactivity:初始化数据监测相关的操作【给data中的对象属性增加setter和getter、包装操作数组的七个方法】和数据代理相关的操作【vm对象代理_data对象】

  • created【生命周期,指的是创建数据监测和数据代理之后】:可以通过vm访问data中的数据和methods中的方法

  • Compile el's outerHTML as template:当new Vue时传入的配置对象中不包含template配置项时会来到该环节,el配置项的值可以是一个选择器,根据选择器能够找到模板中的一段HTML代码片段,这里说的是el的outerHTML,outerHTML和innerHTML的区别如下:

    outerHTML:包含当前标签

    innerHTML:当前标签内部的标签

    这个环节中Vue就开始解析模板【插值语法、计算属性、@click事件类的指令以及其他Vue的指令等等开始解析】了

  • Compile template into render function:当new Vue时传入的配置对象中包含template配置项时会来到该环节,template配置项的值是一个字符串

    通过el配置项给出模板内容容器是会保留的,而通过template配置项给出模板内容原来的容器就会被替换掉【template说谁是模板谁就是模板】。

    注:template中的内容可能需要被一个div之类的根元素【这个根元素还不能是template】所包裹【这就导致每次使用大都需要自己在外层包一个div,最好能够包一个类似template这样的标签,最终的渲染效果中不会出现template,也就不会影响最终的结构,这个情况在Vue2中没有解决方案,Vue3中模仿React给出了解决方案,fragment】,必须保证template中的内容放入容器后只有一个根元素

  • beforeMount【生命周期】:Vue解析模板已经完成了,但还没来得及往页面上放,此时,即使通过document对象操作DOM,最终都是不生效的,这是因为Vue是拿到上一步解析模板得到的虚拟DOM在下一步中转换为真实DOM插入页面的,所以在这个钩子中不要操作DOM。

  • Create vm.$el and replace "el" with it:Vue将前面步骤中生成的虚拟DOM转成了真实DOM,然后将真实DOM向 vm.$el 中存了一份,然后用vm.$el中的真实DOM替换掉el指向的那部分HTML模板代码

    为什么Vue要向vm.$el中存一份真实DOM?

    ​ 在进行新旧虚拟DOM对比时,如果存在可以复用的真实DOM节点,就可以从vm.$el中拿到指定的真实DOM节点进行复用。

  • mounted【生命周期】:页面中展示的是经过Vue编译的DOM,此时,对DOM的操作均有效,但尽量避免自己操作DOM

更新流程:

  • beforeUpdate【生命周期】:数据更新后,数据是新的但页面是旧的,页面还没来得及更新,页面与数据尚未同步

  • Visual DOM re-render and patch:patch是指新旧虚拟DOM的比较

  • updated【生命周期】:数据是新的,页面也是新的

销毁流程:

  • beforeDestroy【生命周期】:当调用vm.$destroy()方法时,vm将调用该钩子。同时,在该钩子中对数据进行的所有操作都不会再触发更新

    官方关于vm.$destroy()方法的描述如下:

    ​ 完全销毁一个实例【vm】。清理它【vm】与其它实例【组件实例对象(一个应用只有一个vm,但一个vm会管理多个组件实例对象【微型vm】)】的连接,解绑它【vm】的全部指令及自定义事件监听器【像@click这种原生DOM事件并不会被解绑】。

  • Teardown watchers child components【弟弟们】 and event listeners

  • destroy【生命周期】:在该钩子中对数据进行的所有操作都不会再触发更新,React中没有该钩子,一般这个钩子里啥也不干

vm销毁后,页面中的DOM并不会消失,只是DOM不再归vm管理

如果是先销毁vm,再打开Vue开发者工具,Vue开发者工具中就看不到Vue实例了【现加载的时候发现没有Vue实例了所以就看不到Vue实例】;如果是先打开Vue开发者工具,再销毁vm,Vue开发者工具中是能够看到Vue实例的,但数据即使再改变,Vue开发者工具中的数据也不会改变,仅仅是个残留

类比vm的生命周期

常用的生命周期钩子:
		1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
		2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

关于销毁Vue实例
		1.销毁后借助Vue开发者工具看不到任何信息。
		2.销毁后自定义事件会失效,但原生DOM事件依然有效。
		3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
<body>
	<!-- 准备好一个容器-->
	<div id="root">
		<h2 :style="{opacity}">欢迎学习Vue</h2>
		<button @click="opacity = 1">透明度设置为1</button>
		<button @click="stop">点我停止变换</button>
	</div>
</body>

<script type="text/javascript">
	Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

	 new Vue({
		el:'#root',
		data:{
			opacity:1
		},
		methods: {
			stop(){
				// 自行触发vm销毁的情况下可以通过这种方式进行更多其他的收尾操作
				this.$destroy()
			}
		},
		//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
		mounted(){
			console.log('mounted',this)
			this.timer = setInterval(() => {
				console.log('setInterval')
				this.opacity -= 0.01
				if(this.opacity <= 0) this.opacity = 1
			},16)
		},
		beforeDestroy() {
			// 其他情况触发了vm销毁的情况下还想进行更多其他的收尾操作只能通过beforeDestroy钩子实现
			clearInterval(this.timer)
			console.log('vm即将驾鹤西游了')
		},
	})

</script>
posted @ 2024-02-29 19:39  刘二水  阅读(58)  评论(0)    收藏  举报