2023Vue面试题剖析原理
- 18.生命周期有哪些
- 19.Vue中的diff算法原理
- diff概念
- diff比较流程
- 20.Vue中key的作用和原理
- key的概念
- key的作用
- 21.Vue.use作用和原理
- use概念
- 插件的功能
- 实现原理
- 22.Vue.extend方法的作用
- Vue.extend概念
- 原理分析
- 23.Vue组件中data为什么必须是函数
- 24.函数式组件的优势
- 25.Vue中过滤器和使用场景
- 26.v-once的使用场景
- v-once概念
- 27.Vue.mixin的使用场景和原理
- Vue.mixin概念
- 混入方式
- minx合并策略
- 28.Vue中slot如何实现及什么时候使用
- 插槽概念
- 什么时候使用
- 插槽的分类和原理
- 29.双向数据绑定的理解和原理
- 双向数据绑定的概念
- 表单元素中的v-model
- 组件中的v-model
- 30.Vue中.sync修饰符的作用
18.生命周期有哪些
19.Vue中的diff算法原理
diff概念
Vue基于虚拟DOM做更新。diff算法的核心是比较两个虚拟节点的差异。Vue的diff算法是平级比较的,不考虑跨级比较的情况。内部采用深度递归+双指针的方式进行比较。
diff比较流程
- 先比较是否是相同节点(key和tag)
- 相同节点比较属性,并复用老节点(将老的虚拟dom复用给新的虚拟节点dom)
- 比较儿子节点,考虑老节点和新节点儿子的情况
- 老的没子节点,现在有子节点,直接插入新的子节点
- 老的有子节点,新的没子节点,直接删除页面节点
- 老的子节点是文本,新的子节点是文本,直接更新文本节点即可
- 老的子节点是一个列表,新的子节点也是一个列表,更新子节点
- 优化比较:两个子节点为列表:头头、尾尾、头尾、尾头,而乱序时创建映射表去复用
- 比较查找进行复用
注:Vue3中采用最长递增子序列来实现diff优化
20.Vue中key的作用和原理
key的概念
- key的特殊属性主要用在Vue虚拟DOM算法,在新旧节点对比时辨别VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。
- 例如:以下两个输入框,输入数据并切换时,数据仍保留,只是类型发生变化了,可加key破坏复用
<input type="text" v-if="!isPassword">
<input type="password" v-else>
- 当Vue正在更新使用v-for渲染元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被该边,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
key的作用
- Vue在patch的过程中,通过key可以判断两个虚拟节点是否是相同节点(可以复用老节点)
- 无key会导致更新的时候出问题(逆序添加,逆序删除等破坏顺序操作)
- 尽量不要采用索引作为key
21.Vue.use作用和原理
use概念
安装Vue.js插件时,如果插件是一个对象,必须提供install方法。如果插件是一个函数,它会被作为install方法。install方法调用时,会将Vue作为参数传入,这样插件中就不需要依赖Vue了。如:Vuex,Vue-Router
插件的功能
- 添加全局指令、全局过滤器、全局组件
- 通过全局混入来添加一些组件选项
- 添加Vue实例方法,通过把他们添加到Vue.prototype上实现
实现原理
Vue.use = function(plugin:Function | Object){
//插件缓存
const installedPlugins = this._installedPlugins || (this._installedPlugins = [])
if(installedPlugins.indexOf(plugin) > -1){
//如果已经有插件,直接返回
return this
}
//添加参数
const args = toArray(arguments, 1) //除了第一项,其它的参数整合成数组
args.unshift(this) //将Vue放入数组中
if(typeof plugin.install === 'function'){
//调用install方法
plugin.install.apply(plugin, args)
}else if(typeof plugin === 'function'){
//直接调用方法
plugin.apply(null, args)
}
installedPlugins.push(plugin) //缓存插件
return this
}
22.Vue.extend方法的作用
Vue.extend概念
使用基础Vue构造器,创建一个“子类”。参数是一个包含组件选项的对象。 data选项是特例,需要注意在Vue.extend( )中它必须是函数。
var Profile = Vue.extend({
template:"<p>{{firstName}}{{lastName}} aka {{alias}}</p>",
data:function(){
return {
firstName:'water',
lastName:'white',
alias:'Hi'
}
}
})
//创建Profile实例,并挂载到一个元素上
new Profile().$mount("#mount-point")
new Vue().$mount()
原理分析
- 所有的组件创建时都会调用Vue.extend方法进行创建
- 有了此方法可以手动挂载组件去指定节点
- 后端存储的字符串模板,可以通过Vue.extend方法将其、进行渲染,但是需要引入编译时
23.Vue组件中data为什么必须是函数
- 根实例对象data可以是对象也可以是函数“单例”,不会产生数据污染情况
- 组件实例对象data必须为函数,目的是为了防止多个组件实例对象之间共用一个data,产生数据污染,所以要通过工厂函数返回全新的data作为组件and数据源
24.函数式组件的优势
- 函数组件的特性:无状态、无生命周期、无this,但是性能高。正常组件是一个类继承了Vue,函数式组件就是普通的函数,没有new的过程。
- 最终就是将返回的虚拟DOM变成真实DOM替换对应的组件
- 函数式组件不会被记录在组件的父子关系中,在Vue3中因为所有的组件都不用new了,所以在性能上没有了优势
25.Vue中过滤器和使用场景
过滤器实质不改变原始数据,只是对数据进行加工处理后放回过滤的数据再进行调用处理,可理解诶为纯函数
{{message | filterA("arg1","arg2") | filterB("arg1", "arg2")}}
Vue.filter('filterA', function(value){
//返回处理后的值
})
Vue.filter('filterB', function(value){
//返回处理后的值
})
常见场景:单位转换、千分符、文本格式化、时间格式化操作。但可使用方法代替,因此Vue3中废弃
<p>{{format(number)}}</p>
const format = (n) =>{
return parseFloat(n).toFixed(2)
}
26.v-once的使用场景
v-once概念
v-once是Vue中内置指令,只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
可用在:单个元素、父节点、组件、列表
vue3.2之后,增加了v-memo指令,通过依赖列表的方式控制页面渲染,如果依赖的属性(valueA,valueB)没有改变,则默认渲染缓存的结果,类似于计算属性
<div>
<div v-memo="[valueA,valueB]">
<div class="box" v-for="item in arr" :key="item">{{item}}</div>
</div>
</div>
27.Vue.mixin的使用场景和原理
Vue.mixin概念
mixin可以用来扩展组件,将公共逻辑进行抽离。在需要改逻辑时进行“混入”,采用策略模式针对不同的属性进行合并。如果混入的数据和本身组件中的数据冲突,会采用“就近原则”以组件的数据为准。
mixin(换入对象)中有很多缺陷:“命名冲突问题”,“数据来源问题”,Vue3中采用组合式API提取公共逻辑非常方便(hook函数)。
混入方式
分为全局混入和局部混入。一般情况下全局混入用于编写插件(如:Vuex,Vue-Router),局部混入用于复用逻辑。
minx合并策略
核心:对象的合并处理
- props、methods、inject、computed同名时会被替换(组件为主)
- data会被合并(组件为主)
- 生命周期和watch方法会被合并成队列
- components、directives、filters会在原型链上叠加(子找到父的)
组件的扩展除了mixin外还有一个属性叫extends,但不常用
28.Vue中slot如何实现及什么时候使用
插槽概念
插槽设计来源于Web Components规范草案,利用slot进行占位,在使用组件时,组件标签内部内容会分发到对应的slot中
什么时候使用
通过插槽可以让用户更好的对组件进行扩展和定制化。可以通过具名插槽指定渲染的位置,常用的组件例如:弹框组件、布局组件、表格组件、树组件…
插槽的分类和原理
- 默认插槽
- 具名插槽
- 作用域插槽
本质区别:普通插槽,渲染在父级;作用域插槽,渲染在组件内部
29.双向数据绑定的理解和原理
双向数据绑定的概念
Vue中双向数据绑定靠的是执行v-model,可以绑定一个动态值到视图上,同时修改视图能改变数据对应的值(能修改的视图就是表单组件)经常会听到一句话:v-model是value+input的语法糖
表单元素中的v-model
内部会根据标签的不同解析出不同的语法。并且有“额外”的处理逻辑
- 例如:文本框会被解析为value+input事件
- 例如:复选框会被解析为checked+change事件
- …
组件中的v-model
组件上的v-model默认会利用名为value的prop和名为input的事件。对于组件而言v-model就是value+input的语法糖。可用于组件中数据的双向绑定。
如果组件中有多个数据想做双向数据绑定怎么办?很遗憾在Vue2中不支持使用多个v-model(可使用.sync语法),Vue3中可以通过以下方式进行绑定
<my v-model:a="a" v-model:b="b" v-model:c="c"></my>
30.Vue中.sync修饰符的作用
在有些情况下,需要对一个prop进行“双向绑定”,这时可以使用.sync来实现。v-model默认只能双向绑定一个属性,可用过.sync修饰符绑定多个属性。
<my :a.sync="a" :b.sync="b"></my>
Vue3中.sync语法已被移除