Vue生命周期源码解读(大厂面试必备)
Posted hugo233
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue生命周期源码解读(大厂面试必备)相关的知识,希望对你有一定的参考价值。
什么是生命周期?
Vue的实例具有生命周期,Vue的实例在生成的时候,会经历一系列的初始化的过程;数据的监听,编译模板,实例挂载DOM元素,或者数据更新导致DOM更新,在执行的过程中,会运行一些叫做生命周期的钩子函数,在Vue实例生命周期中特定的时间点执行的函数称为生命周期的钩子函数;
如果我们需要在某个生命周期处理一些事情,我们可以把这些事情写在钩子函数中;等到Vue的实例生命周期到这个阶段就会执行这个钩子,而我们要做的事情也就得以处理了;
生命周期的钩子函数不能人为的控制其执行的顺序。
Vue生命周期梳理
总的来说,Vue的生命周期可以分为以下八个阶段:
- beforeCreate 实例创建前
- created 实例创建完成
- beforeMount 挂载前
- mounted 挂载完成
- beforeUpdate 更新前
- updated 更新完成
- beforeDestory 销毁前
- destoryed 销毁完成
大家可以参考一下官方资料 vue.js
1. vue实例化过程
从vue实例化开始分析,我们通过new Vue来实例化来查看一下源码 在 src/core/instance/init.js 中定义 使用vscode的小伙伴推荐使用Search node_modules插件查找node_modules中的插件方便多了,妈妈再也不用担心我迷路了
Vue.prototype._init = function (options?: Object) {
// ... 省略代码
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
vm._name = formatComponentName(vm, false)
mark(endTag)
measure(`vue ${vm._name} init`, startTag, endTag)
}
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等,vue 把不同的功能逻辑拆成一些单独的函数执行。
我们关注到,在这个过程中插入钩子函数,提供给开发者调用的机会。在初始化的最后,检测到如果有 el 属性,则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM。
2.生命周期钩子
- 生命周期钩子自动绑定this到实例上,因此你可以通过this.操作访问到数据和方法。注意不能使用箭头函数例如下方代码,因为箭头函数绑定外层的this会一直往上找。
created:()=>{// ...代码}
- 下面用在各个生命周期中打印下el,data,dom节点
export default {
name: 'App',
data() {
return {
title: '标题'
}
},
methods: {
onDestoryClick() {
this.$destroy()
}
},
beforeCreate() {
console.log(
`\\n\\nbeforeCreate打头\\n$el :${this.$el}\\n$data :${JSON.stringify(
this.$data
)}\\n$refs.head :${JSON.stringify(
this.$refs.head
)}\\nbeforeCreate结尾\\n\\n`
)
console.log(this.$vnode)
},
created() {
console.log(
`\\n\\ncreated打头\\n$el :${this.$el}\\n$data :${JSON.stringify(
this.$data
)}\\n$refs.head :${JSON.stringify(this.$refs.head)}\\ncreated结尾\\n\\n`
)
console.log(this.$vnode)
},
beforeMount() {
console.log(
`\\n\\nbeforeMount打头\\n$el :${this.$el}\\n$data :${JSON.stringify(
this.$data
)}\\n$refs.head :${JSON.stringify(this.$refs.head)}\\nbeforeMount结尾\\n\\n`
)
console.log(this.$vnode)
},
mounted() {
console.log(
`\\n\\nmounted打头\\n$el :${this.$el}\\n$data :${JSON.stringify(
this.$data
)}\\n$refs.head :${JSON.stringify(this.$refs.head)}\\nmounted结尾\\n\\n`
)
console.log(this.$vnode)
}
}
可以发现
-
beforeCreate中拿不到任何数据,它在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
-
created中已经可以拿到data中的数据了,但是dom还没有挂载。会判断有无el,如果没有el则停止后面的模板挂载。
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
使用场景:ajax请求和页面初始化
-
beforeMount 和 created 拿到的数据相同 在挂载开始之前被调用:相关的 render 函数首次被调用。
-
mounted中el被创建dom已经更新,vue实例对象中有template参数选项,则将其作为模板编译成render函数,编译优先级render函数选项 > template选项
使用场景:常用于获取VNode信息和操作,ajax请求
注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.$nextTick 替换掉 mounted
-
由于beforeUpdate和updated使用的比较少,一般用计算属性和watch代替所以在此不在说明
-
destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
客户端渲染过程
- 处理 html 标记并构建 DOM 树。
- 处理 CSS 标记并构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树。
- 根据渲染树来布局,以计算每个节点的几何信息。
- 将各个节点绘制到屏幕上。
最后,给大家分享一份2021最新Vue面试题含源码解析。由于篇幅原因,仅展示一部分面试题详解,更多最新的Vue面试题整理成了一个PDF,需要的朋友【点这里】免费领取。
vue-cli工程
- 构建的 vue-cli 工程都到了哪些技术,它们的作用分别是什么?
- vue-cli 工程常用的 npm 命令有哪些?
- 请说出vue-cli工程中文件夹和文件的用处
- config文件夹 下 index.js 的对于工程 开发环境 和 生产环境 的配置
- 请你详细介绍一些 package.json 里面的配置
vue核心知识点
- 对于Vue是一套渐进式框架的理解
- vue.js的两个核心是什么?
- 请问 v-if 和 v-show 有什么区别
- vue常用的修饰符
- v-on可以监听多个方法吗?
- vue中 key 值的作用
- vue-cli工程升级vue版本
- vue事件中如何使用event对象?
- $nextTick的使用
- Vue 组件中 data 为什么必须是函数
- v-for 与 v-if 的优先级
- vue中子组件调用父组件的方法
- vue中 keep-alive 组件的作用
- vue中如何编写可复用的组件?
- 什么是vue生命周期?
- vue生命周期钩子函数有哪些?
- vue如何监听键盘事件中的按键?
- vue更新数组时触发视图更新的方法
- vue中对象更改检测的注意事项
- 解决非工程化项目初始化页面闪动问题
- v-for产生的列表,实现active的切换
- v-model语法糖的组件中的使用
- vue中自定义过滤器
- vue等单页面应用及其优缺点
- 什么是vue的计算属性?
- vue-cli提供的几种脚手架模板
- vue父组件如何向子组件中传递数据?
- vue弹窗后如何禁止滚动条滚动?
- 计算属性的缓存和方法调用的区别
- vue-cli中自定义指令的使用
vue-router
- vue-router如何响应 路由参数 的变化?
- 完整的 vue-router 导航解析流程
- vue-router有哪几种导航钩子( 导航守卫 )?
- vue-router传递参数的几种方式
- vue-router的动态路由匹配
- vue-router如何定义嵌套路由?
- 组件及其属性
- vue-router实现路由懒加载( 动态加载路由 )
- vue-router路由的两种模式
- history路由模式配置及后台配置
vuex
- 什么是vuex?
- 使用vuex的核心概念
- vuex在vue-cli中的应用
- 在vue中使用vuex,修改state的值
- vuex actions异步修改状态
http请求
- Promise对象是什么?
- axios、fetch与ajax有什么区别?
- 什么是JS的同源策略和跨域问题?
- 如何解决跨域问题?
- axios有什么特点?
UI样式
- .vue组件的scoped属性的作用
- 如何让CSS只在当前组件中起作用?
- vue-cli中常用的UI组件库
- 如何适配移动端?【 经典 】
- 移动端媒体查询
- vue内容垂直和水平居中
- vue-cli引入图片的方法
- 移动端常见样式问题
- 文本超出隐藏
常用功能
- vue中如何实现tab切换功能?
- vue中keep-alive 实现标签页组件缓存
- vue中实现页面从右往左侧滑入效果
- vue中父子组件如何相互调用方法?
- vue中央事件总线的使用
MVVM设计模式
- MVC、MVP与MVVM模式
- MVC、MVP与MVVM的区别
- MVVM的实现原理
- Object.defineProperty()方法
- ES6中定义的类和对象
- JS中的文档碎片
- 解构赋值
- Array.from
- Array.reduce
- 递归的使用
- Obj.keys()与Obj.defineProperty
- 发布-订阅模式
- vue项目优化,缩短首屏加载时间
深入拓展
- vue开发命令 npm run dev 输入后的执行过程
- vue的服务器端渲染
- 从零写一个npm安装包
- vue-cli中常用到的加载器
- webpack的特点
快速入手通道:【点击这免费领取2021最新Vue面试题含源码解析】
你的支持,我的动力;祝各位前程似锦,offer不断!!!
以上是关于Vue生命周期源码解读(大厂面试必备)的主要内容,如果未能解决你的问题,请参考以下文章