16. v-if和v-for的优先级问题
- Vue 2:
v-for
的优先级高于v-if
,v-if
中可以使用v-for
的变量(优化点:使用filter
优化v-if
的选择)。 - Vue 3:
v-if
的优先级更高,v-if
不能使用v-for
中的变量,编译后会把v-if
提升到外层标签上。
17. 生命周期有哪些
Vue 2 中的生命周期
- beforeCreate: 初始化父子关系及事件,数据观测之前被调用。一般编写插件时会用到。
- created: 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测,属性和方法等,但是这里没有
$el
,一般也不怎么用。 - beforeMount: 在挂载开始之前被调用,相关的
render
函数首次被调用。 - mounted:
el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子。可以用于获取DOM元素。 - beforeUpdate: 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。此时修改数据不会再次触发更新方法。
- updated: 由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。
- beforeDestroy: 实例销毁之前调用。在这一步,实例仍然完全可用。
- destroyed: Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
- keep-alive:
activated
和deactivated
。
Vue 3 的生命周期
和Vue 2类似,beforeDestroy
、destroy
改成beforeUnmount
、unMount
。组合式API中删除了beforeCreate
、created
,新增了setup
。
18. Vue中的diff算法
Diff概念
Vue基于虚拟DOM做更新。Diff的核心就是比较两个虚拟节点的差异。Vue的diff算法是平级比较,不考虑跨级比较的情况。内部采用深度递归的方式 + 双指针的方式进行比较。
- Diff比较流程:
- 先比较是否是相同节点(key tag)。
- 相同节点比较属性,并复用旧节点(将旧的虚拟DOM复用给新的虚拟节点DOM)。
- 比较子节点,考虑旧节点和新节点子节点的情况:
- 旧的没有子节点,现在有子节点:直接插入新的子节点。
- 旧的有子节点,新的没有子节点:直接删除页面节点。
- 旧的子节点是文本,新的子节点是文本:直接更新文本节点即可。
- 旧的子节点是一个列表,新的子节点也是一个列表(updateChildren)。
- 优化比较:头头、尾尾、头尾、尾头。
- 比对查找进行复用映射表。
Vue3中采用最长递增子序列来实现diff优化。
19. Vue中key的作用和原理
Key的概念
Key的特殊attribute主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes。如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能地尝试就地修改/复用相同类型元素的算法。当Vue正在更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲
Key的作用
- 可以复用旧节点。Vue在patch过程中通过key可以判断两个虚拟节点是否是相同节点。
- 无key会导致更新的时候出问题。
- 尽量不要采用索引作为key。
20. Vue.use是干什么的
1. use概念
安装Vue.js插件。如果插件是一个对象,必须提供install方法。如果插件是一个函数,它会被作为install方法。install方法调用时,会将Vue作为参数传入,这样插件中就不再需要依赖Vue了。
2. 插件的功能
- 添加全局指令、全局过滤器、全局组件。
- 通过全局混入来添加一些组件选项。
- 添加Vue实例方法,通过把它们添加到vue.prototype上实现。