v-show 和 v-if 区别
- v-show 通过 CSS display 控制显示和隐藏
- v-if 组件真正的渲染和销毁,而非显示隐藏
- 频繁切换显示状态用 v-show,否则用 v-if
为何在 v-for 中使用 key
- 必须用 key,且不能是 index 和 random
- diff 算法中通过 tag 和 key 来判断是否是 sameNade
- 减少渲染次数,提升渲染性能
描述 Vue 组件的生命周期 (父子组件)
- 挂载阶段 created mounted
created 并未开始渲染,Vue 实例已初始化完毕,仅存在于内存
mounted 渲染完毕 - 更新阶段 updated
- 销毁阶段 destroyed
(父子组件)
- created 创建:外到内(父到子)
- mounted 渲染:内到外
- updated 更新:由外到内开始,由内到外结束
- destroyed 销毁:由外到内开始,由内到外结束
Vue 组件如何通讯 (常见)
- 父子组件 props 和 this.$emit
- 自定义事件
- vuex
描述组件的渲染更新过程
双向数据绑定 v-model 的实现原理
- input 元素的 value = this.name
- 绑定 input 事件 this.name = $event.target.value
- data 更新触发 re-render
对于 MVVM 的理解
computed 有何特点
- 缓存,data 不变不会重新计算
- 提高性能
为何组件 data 必须是一个函数
- Object 是引用数据类型,如果不用 function 返回,每个组件的 data 都是内存的同一个地址,一个数据改变了其他也改变了
- JavaScript 只有函数构成作用域(注意理解作用域,只有函数{}构成作用域,对象的{}以及 if(){}都不构成作用域,data 是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。
ajax 请求应该放在哪个生命周期
- mounted
- JS 是单线程,ajax 异步获取数据
- 放在 mounted 之前没有用 (存在异步队列中),只会让逻辑更加混乱
如何将组件所有的 props 传递给子组件
- $props
如何自己实现 v-model
<template>
<!-- 例如:vue 颜色选择 -->
<input type="text" :value="text1" @input="$emit('change1', $event.target.value)" />
<!--
1. 上面的 input 使用了 :value 而不是 v-model
2. 上面的 change1 和 model.event1 要对应起来
3. text1 属性对应起来
-->
</template>
<script>
export default {
model: {
prop: 'text1', // 对应 props text1
event: 'change1',
},
props: {
text1: String,
default() {
return ''
},
},
}
</script>
多个组件有相同逻辑,如何抽离
- mixin
- 缺点
何时要使用异步组件
- 加载大组件
- 路由异步加载
何时需要使用 keep-alive
- 缓存组件,不需要重复渲染
- 如多个静态 tab 页的切换
- 优化性能
何时需要使用 beforeDestroy
- 解绑自定义事件 event.$off
- 清除定时器
- 解绑自定义 DOM 事件,如 window scroll 等
什么是作用域插槽
- 略
Vuex 中 action 和 mutation 区别
- action 中处理异步, mutation 不可以
- mutation 做原子操作
- action 可以整合多个 mutation
Vue-router 常用的路由模式
- hash 默认
- H5 history 需服务端支持
- 二者比较
如何配置 vue-router 异步加载
component: () => import('./xxx')
用 vnode 描述一个 DOM 结构
{
tag: 'div',
props: {
className: 'container',
id: 'div1'
},
children: [
{
tag: 'p',
children: 'vdom'
},
{
tag: 'ul',
props: {style: 'font-size: 20px'},
children: [
{
tag: 'li',
children: 'a'
}
// ...
]
}
]
}
监听 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-show 和 v-if
- 合理使用 computed
- v-for 加 key ,避免和 v-if 同时使用
- 自定义事件、DOM 事件及时销毁
- 合理使用异步组件
- 合理使用 keep-alive
- data 层级不要太深
- 使用 vue-loader 在开发环境进行模板编译(预编译)
- webpack 层面的优化
- 前端通用的性能优化,如图片懒加载
- 使用 SSR