Vue面试题(持续更新)
1.v-show和v-if的区别
v-show是切换元素的显示状态即显示与隐藏,修改的是元素的display值
v-if也是切换元素的显示与隐藏,但是是在操作dom
相同点: 都能让页面元素达到显示隐藏的效果
不同点: 一个是操作display,一个是操作dom。
v-if组件真正的是渲染与销毁,如果频繁的切换显示与隐藏效果,v-if的开销比v-for更大,使用v-for更好
2.为何在v-for中是用key
首先最浅层的就是vue中列表循环需要加上一个key,不然系统就会报错,这是最浅显的。
深度一点的来说就是因为vue的组局高度复用性 增加key可以标识组件的唯一性(有点类似id),可以更好区别各个组件key的作用来高效的更新虚拟dom。
官方原话是:Vue 默认按照“就地更新”的策略来更新通过 v-for`渲染的元素列表。当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
默认模式是高效的,但只适用于列表渲染输出的结果不依赖子组件状态或者临时 DOM 状态 (例如表单输入值) 的情况。
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key
*diff算法中通过tag和key来判断,是否是sameNode
3.描述vue组件生命周期(父子组件)
vue的生命周期就不在多说了,这里只放vue2和vue3生命周期的对比
beforeCreate -> 使用 setup()
created -> 使用 setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
errorCaptured -> onErrorCaptured
父子间生命周期:
加载渲染阶段:父beforeCreate->父Create->父beforeMounte-> 子beforeCreate->子Create->子ceforeMounte
挂载:子Mounte->父Mounte
更新:
1.父更新子不更新:父beforeUpdata->父updata
2.子更新父不更新:子beforupdata->子updata
3.父子一起更新:父beforeupdata->子beforeupdata->子updata->父updata
销毁:
父beforeDestroy->子beforeDestroy->子Destroy->父Destroy
4.Vue组件如何通讯
父传子prop,子传父this.$emit
兄弟间传 event.$no
event.$off
event.$emit
vuex公共仓库
5.描述组件渲染和更新的过程
- 解析模板为 render 函数
这部分是说vue 编译相关,也就是说把 vue 语法编译 成 js 语法,通过执行 vue-template-compiler 的 compiler 函数,得到 render
- 触发响应式
响应式关键 Object.defineProperty(),将模版初次渲染使用到的变量绑定到 Object.defineProperty() 中,首次渲染会 触发 getter
- 执行render 函数
之前得到render函数,现在要执行render函数, 将 vue 语法转成 h 函数的结果,也就是 vNode,后续进行一系列操作
然后更新视图
6.vue-router中history和hash模式区别
hash: 不会刷新页面,也不会发起新的http请求,只是实现客户端页面的定位,#后面的字符不会发送到服务端,#可以修改浏览器的访问历史记录。hash是通过改变锚点(#)来更新页面,并不会让页面重新加载
history与hash区别: history路径没有#号,hash有,history每次改变路径要重新请求文件资源即刷新页面和重发http请求,history是通过window.history实现跳转
7.v-model直接绑定vuex状态可以吗?怎么处理?
官网原话:由于 Vuex 提供的是 mapGetters 和 mapActions 对属性行获取和操作,所以无法直接适配 v-model 的双向绑定形式
解决办法:
-
重写 input 的双向绑定
-
另外一种是提供单独的计算属性,并写明 get / set 方法,将 vuex 的 mapGetters / mapActions 分别赋值