Vue2面试题汇总
vue2前端面试题
- vue2响应式原理
核心原理:
对象:通过defineProperty对对象的已有属性值的读取和修改进行劫持(监视、拦截)
数组:通过重写数组一系列的方法来实现元素修改的劫持
问题:
对象直接添加的属性或者删除已有属性,界面不会自动更新
直接通过下标替换元素或者更新length,界面不会自动更新 - 虚拟节点是什么?
vue中没有真实Dom节点,都是虚拟节点。虚拟节点是一个描述真实dom的js对象,至少包含tag属性、VNodeData属性(描述当前节点有哪些属性),VNodeChildren属性(描述当前节点有哪些子节点,特殊子节点为innerTest)。
vue的视图更新是通过虚拟节点的同级对比,更新虚拟节点树,然后通过diff算法把不同的部分的虚拟节点转化为真实节点来更新视图。 - 虚拟节点是何时生成的
在beforeMount和mounted之间生成,template上的变量也是在这个过程中求得的,data响应式数据也是在这个时候触发getter并收集依赖的。 - 虚拟DOM的更新(data中的数据一修改就会更新到视图上吗?)
虚拟Dom的更新不会直接操作dom,而是更新虚拟Dom JS对象,然后渲染如果存在1000条数据遍历渲染,虚拟DOM会合并赋值和查找动作一次性渲染(1000js对象查找,1000js赋值),一次渲染。 - 什么是diff算法?

差异比较算法的一种,把树形结构按照层级分解,只比较同级元素。不同层级的节点只有创建和删除操作。其原理diff算是平级比较,不考虑跨级不比较的情况;内部采用深度递归的方式和双指针进行比较。 - 数据劫持可以精准的探测数据变化,为什么还要进行diff检测差异?
因为使用响应式数据变化。如果每个属性都添加watcher的话,性能会非常差。粒度过细,会导致更新不精准。 - vue是如何编译template为虚拟节点的?
template(模板): 描述状态和DOM之间的映射关系。
编译模板就是通过一个combile方法把模板编译成AST虚拟语法树,最终转换成一个render函数,通过该render函数可以生成虚拟节点。 - vue的生命周期

- updated和watch的区别
updated: 视图更新就触发,不能知道本次更新是由哪个数据变化导致的,具有响应式效果的数据变化,都能触发。
watch: 数据变化就触发,监听哪个数据,就触发哪个方法。 - nextTick的原理和使用场景
使用原理:vue是异步执行dom更新的,一旦观察到数据变化,vue就会开启一个队列,然后把在同一事件循环当中观察到数据变化的watcher推送进这个队列,如果这个watcher被触发多次,只会被推送到队列一次,这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和dom操作,这样可以提高渲染效率。因此如果要获取更新后的dom元素,可以使用vue内置的$nextTick方法,参数是一个函数;作用是进行执行异步的操作。
应用中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick可以获取数据更新后最新dom的变化。
场景:1)第三方插件,在vue生成的某些dom动态发生变化时重新应用该插件。2)视图更新之后,基于新的视图进行操作。 - vue中的组件缓存
需要缓存情况:当我们在浏览新闻列表,就比如打开一篇新闻,看完点返回,主页却重新加载,刚刚的模块就被记忆清除,这是因为路由的跳转,会导致组件的销毁和重建,这样对用户的体验感差了许多,所以良好的用户体验就是点击返回后看到跳转前的情况。
解决方法使用缓存组件keep-alive,属性:include和exclude - keep-alive理解
vue内置组件,能在组件切换时将状态保留在内存中,防止重复渲染dom;且keep-alive不会在DOM中渲染。 - vue初始化页面闪动问题
因为在 Vue 代码尚未解析之前,尚无法控制页面中 DOM 的显示,所以看见模板字符串等代码。
解决方法是在css中添加 v-cloak,这是官方文档 https://cn.vuejs.org/v2/api/#v-cloak。
[v-cloak] {
display: none;
}
<div v-cloak>{{ message }}</div>
如果没有彻底解决,需要在根元素上加:这里默认vue实例绑定到类名为app的div上。
<div class="app" style="display: none;" :style="{display: 'block'}">
{{message}}
</div>
原理:vue在渲染之前,style="display: none;"让页面不显示。vue渲染完成了,:style="display: block;"让页面显示。
14. Vue.set解决了什么问题?
解决了Vue无法检测data中数组和对象的变化。
Vue不允许动态添加根级响应式属性。
15. vue2中数组响应式的方法
push()、pop()、shift()、unshift()、splice()、sort()、reverse()、
16. Vue.use和Vue.prototype区别
Vue.use和Vue.prototype没有本质区别,Vue.use就是在Vue.prototype基础上又封装了一层而已,他们实现的原理都是在Vue.prototype上添加了一个方法。
Vue.prototype适合于注册Vue生态外的插件,Vue.use适合于注册Vue生态内的插件。
Vue.use()往全局注入一个插件,供全局直接使用, 不需要单独引用。接收函数或者一个包含install
属性的对象为参数
17. Vue中的data为什么是函数?
因为组件是可以复用的,js里对象是引用关系,如果组件data是一个对象,那子组件的data属性值会互相污染,产生副作用。
18. vue计算属性和普通方法的区别
计算属性中的数据不改变时,不会重新执行计算属性(因为计算属性有缓存);vue中的方法视图更新时;vue中的方法就会重新执行。
19. vue的计算属性和watch侦听属性的区别
computed计算属性:依赖其他属性值,并且有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算。一对多的关系。computed会默认执行一次。
watch:更多是观察作用,无缓存性,指定数据的监听回调。一对一的关系,watch可以有异步操作,computed不能有异步操作,否则返回值为undefined;不应该使用箭头函数,理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,watch默认不会执行一次,需要设置才会默认执行。
20. watch和computed的使用场景
watch的使用场景:一个数据影响多个数据,需要在数据变化时执行异步操作或者开销较大的操作时使用。 例如:购物车商品结算的时候
computed:一个数据受多个数据影响,处理复杂的逻辑或多个属性影响一个属性的变化时使用。 例如:搜索数据
21. v-if和v-for的优先级,v-if和v-for同时使用会造成什么,怎么解决
vue2中v-for优先级较高。两者一起使用会浪费性能开销。可以先做if判断再进行for或者使用计算属性先过滤不需要显示的选项再进行循环。
22. v-for,key值的作用,用index值用作key会有什么问题。
key 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法(就地复用)。而使用 key 时,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有唯一的key。重复的 key 会造成渲染错误。
使用index案例:动态下拉框
const options = [
{ text: '选项1', id: 1 },
{ text: '选项2', id: 2 },
{ text: '选项3', id: 3 },
{ text: '选项4', id: 4 }
]
<select>
<option v-for="(item, index) in options" :key="index">
{{ item.text }}
</option>
</select>
如果选中选项3,再删除选项2,选中的值变成选项4,因为key值取index,如今key值为3绑定的是选项
4
当删除选项2时,后面选项的index值和key值的绑定关系变化全部变化,所以重新渲染,这影响性能。
- v-model的实现原理
通过给元素绑定不同的事件获取视图数据并保存到vue实例上,例如input事件,就是通过视图改变数据,再通过v-bind绑定数据到value属性上,就是这样通过数据更新视图。 - v-html会导致什么问题
不安全,容易遭到xss攻击。会替换掉标签内的子元素或者组件。 - 组件通信的方法
父 - > 子组件通信: 属性传值,通过props接受。
子 -> 父组件通信:$emit。
兄弟组件: bus传值,$on、$children、$parent获取当前组件的父组件和子组件。ref传值
多层传参使用$attrs,结合inheritAttrs: false。 - 子组件是通过什么触发父组件的方法的,原理是什么
通过$emit触发,父组件通过引入赋值把自身方法赋值给子组件的$listeners属性,子组件通过调用自身$listeners属性上对应的方法来调用父组件方法的。 - 父子组件钩子函数的执行顺序
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子
beforeMount -> 子mounted -> 父mounted
父beforeUpdate->子beforeUpdate->子updated->父updated
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed - mixin的使用场景和原理
混入(mixins)是一种分发Vue组件中可复用功能的非常灵活的方式。混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。作用是抽离公共的业务逻辑,原理类似对象的继承,当组件初始化的时候,会调用mergeOptions方法进行合并。如果混入的数据和本身组件的数据有冲突,采用本身的数据为准。 - mixins和父子组件的生命周期执行顺序
mixins的beforeCreate > 父beforeCreate > mixins的created > 父created > mixins的beforeMount > 父beforeMount > 子beforeCreate > 子created > 子beforeMount > 子mounted > mixins的mounted >父mounted - 说说vue是渐进式框架的理解
渐进式的意思大概是可扩展的,例如,只有一个el选项也是vue程序,10个el选项也是vue程序,可根据需求不断增加选项扩展实现更多功能,例如增加data,computed,watch等等。由简入繁,良好兼容。 - 谈谈你对MVVM的理解
映射关系简化,MVVM在MVC的基础上隐藏了控制层。vue是一个MVVM框架,它是一个视图层框架,viewModal是一个桥梁,将数据和视图进行关联。 - vue的两个核心是什么?
data数据层和view视图层。
vue的核心体系是一套响应式的体系,数据变化响应式更新视图的体系。 - vue常见的性能优化(可以具体到不同方向,给他个示例)
(1)代码优化:组件复用、事件代理、watch\computed、v-if/v-show、路由懒加载、防抖节流等。
(2)加载性能优化:按需加载、图片懒加载、滚动到可视区域动态加载等
(3)打包优化cdn、多线程打包、sourceMap生成、缓存和压缩优化
(4)SEO优化 - SPA单页面应用的优缺点
SPA单页面应用:一次性从服务器下载,切换页面不用再发送页面请求,只发送对应页面的图片、数
据等请求
优点:
(1)无刷新界面,给用户体验原生的应用感觉
(2)节省原生(android和ios)app开发成本
(3)提高发布效率,无需每次安装更新包
(4)容易借助其他知名平台更有利于营销和推广
(5)符合web2.0的趋势
缺点:
(1)效果和性能确实和原生的有较大差距
(2)各个浏览器的版本兼容性不一样
(3)业务随着代码量增加而增加,不利于首屏优化
(4)某些平台对hash有偏见,有些甚至不支持pushstate
(5)不利于搜索引擎抓取 - Vue如何定义一个全局访问的方法
(1) 利用全局混入mixin定义全局方法。
(2) 通过prototype挂载定义全局方法。
(3) 直接在vue文件中定义全局方法($root,$emit,$on)。 - v-on如何绑定多个事件
// v-on绑定多个方法(采用的是对象形式)
<button v-on="{click: clickMethods, mousemove: mouseMethods}">按钮<button> 2.v-on
//一个事件绑定多个方法 (语法糖 @)
<button @click="click1,click2">按钮</button>
更多推荐


所有评论(0)