Vue
面试题
v-show
和v-if
之间的区别
v-show
通过css display
控制显示与隐藏v-if
组件真正的渲染和销毁,而不是显示和隐藏- 频繁切换显示状态用
v-show
,否则用v-if
为何
v-for
中要用key
- 必须用
key
,而且不能是index
和random
diff
算法中通过tag
和key
来判断,是否为sameNode
- 减少渲染次数,提升渲染性能
描述
Vue
组件生命周期(有父子组件的情况)
- 单组件生命周期
- 挂载阶段
- 更新阶段
- 销毁阶段
- 父子组件生命周期关系
- 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
- 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
- 父组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated
- 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
- 加载渲染过程
Vue
组件如何通讯
- 父子组件
props
和this.$emit
- 自定义事件
event.$on event.$off event.$emit
Vuex
描述组件渲染和更新的过程
-
一个组件渲染到页面,修改
data
触发更新(数据驱动视图) -
响应式:监听
data
属性getter setter
(包括数组) -
模板编译:模板到
render
函数,再到vnode
-
vdom:patch(elem,vnode) 和 patch(vnode,newVnode)
-
初次渲染过程
- 解析模板为
render
函数(或在开发环境已完成,vue-loader
) - 触发响应式,监听
data
属性getter setter
- 执行
render
函数,生成vnode , patch(elem,vnode)
- 解析模板为
-
更新过程
- 修改
data
,触发setter
(此前在getter
中已经被监听) - 重新执行
render
函数,生成newVnode
patch(vnode,newVnode)
- 修改
-
完整流程图
双向数据绑定
v-model
的实现原理
input
元素的value = this.name
- 绑定
input
事件this.name = $event.target.value
data 更新触发 render
对
mvvm
的理解
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-829xVsV9-1588586481086)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200504155932871.png)]
computed
有何特点
- 缓存,
data
不变不会重新计算 - 提高性能
为何组件
data
必须是一个函数
- 每个实例可以维护一份被返回对象的独立的拷贝
ajax
请求应该放在那个生命周期中
- 在
created
的时候,视图中的dom
并没有渲染出来,所以此时如果直接去操dom
节点,无法找到相关的元素 - 在
mounted
中,由于此时dom
已经渲染出来了,所以可以直接操作dom
节点 - 一般情况下都放到
mounted
中,保证逻辑的统一性,因为生命周期是同步执行的,ajax
是异步执行的 - 服务端渲染不支持mounted方法,所以在服务端渲染的情况下统一放到created中
如何将组件所有
props
传递给子组件
$props
:当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象 property 的访问。<User v-bind="$props">
自定义组件的
v-model
<input type="text" :value="myValue" @input="$emit('change',$event.target.value)">
//1、上面使用的:value 没有使用 v-modle
//2、上面的 change 和 model.event 对应起来即可
export default{
model :{
prop:'myValue',// 对应到 props myValue
event:'change'
},
props :{
myValue:String
}
}
多个组件有相同的逻辑,如何抽离
mixins:[myMixin]
可以添加多个,会自动合并起来Vue3
提出的Composition API
旨在解决这些问题- 以及
mixin
的一些缺点- 变量来源不明确,不利于阅读
- 多
mixin
可能会造成命名冲突 mixin
和组件可能出现多对多的关系,复杂度较高
何时使用异步组件
- 加载大组件
- 路由异步加载
何时使用
keep-alive
- 缓存组件,不需要重复渲染
- 多个静态
tab
页的切换 - 优化性能
何时需要使用
beforeDestory
- 解绑自定义事件
event.$off
- 清除定时器
- 解绑自定义的
DOM
事件,如window scroll
Vuex
中action
和mutation
有何区别
action
中处理异步,mutation
不可以mutation
做原子操作action
可以整合多个mutation
Vue-router
常用的路由模式
hash
默认H5 history
(需要服务端支持)
如何配置
Vue-router
异步加载
-
const router = new VueRouter({ routes: [ { path: '/foo', component: () => import(/* webpackChunkName: "group-foo" */ './Foo.vue') } ] })
vnode
描述一个dom
结构
<div id="container">
<h1 class="title">
JS模拟DOM
<span>哈哈</span>
</h1>
<p class="content">模拟模拟</p>
</div>
const Vnode = {
tag: "div",
attr: {
id: "container"
},
children: [
{
tag: "h1",
attr: {
class: "title"
},
children: [
"JS模拟DOM",
{
tag: "span",
children: [
"哈哈"
]
}
]
},
{
tag: "p",
attr: {
class: "content"
},
children: [
"模拟模拟"
]
}
]
}
监听
data
变化的核心API
是什么
Object.defineProperty
- 以及深度监听、监听数组
Vue
如何监听数组变化
Object.defineProperty
不能监听数组变化- 重新定义原型,重写
push pop
等方法,实现监听 Proxy
可以原生支持监听数组变化
描述响应式原理
- 监听
data
变化 - 组件渲染和更新的流程
diff
算法的事件复杂度
O(N)
- 在
O(N^3)
基础上做了一些调整
简述
diff
算法过程
patch(elem,vnode) patch(vnode,newVnode)
patchVnode addVnodes removeVnodes
updateChildren
(key
的重要性)
Vue
为何是异步渲染,$nextTick
何用
- 异步渲染(以及合并
data
修改),以提高渲染性能 $nextTick
在DOM
更新完之后,触发回调
Vue
常见性能优化方式
- 合理使用
v-shoe
和v-if
- 合理使用
computed
v-for
时加key
,以及避免和v-if
同时使用- 自定义事件、
DOM
事件及时销毁 - 合理使用异步组件
- 合理使用
keep-alive
data
层级不要太深- 使用
vue-loader
在开发环境做模板编译(预编译) webpack
层面的优化- 前端 通用的性能优化,如图片懒加载
- 使用
ssr
如何应对上述面试题
- 框架的使用(基本使用,高级特性,周边插件)
- 框架的原理(基本原理的了解,热门技术的深度,全面性)
- 框架的实际应用,即设计能力(组件结构,数据结构)