vue面试题-第一弹
...大约 6 分钟
组件间通信的方式
根据组件之间的关系讨论组件通信最为有效
- 父子组件
- props/parent/ref/$attrs
- 兄弟组件
- parent/vuex/eventbus
- 跨层级关系
- eventbus / vuex / prpvate + inject
v-for 和 v-if 那个优先级更高
- 实践中 不应该把 v-for 和 v-if 放在一起
- 在 vue2 中,v-for 的优先级高于 v-if 把他们放在一起。输出的渲染函数中已可看出会限制性循环再判断条件,哪怕我们只渲染列表中的一小部分,也得在每次重新渲染的时候遍历整个列表,这会比较浪费,另外需要注意的是在 vue3 中则完全相反,v-if 的优先级大于 v-for,所以在执行 v-if 的时候,它调用的变量还不存在,就会导致异常
- 通常有两种情况会导致我们这样做
- 为了过滤列表中的项目,此时定义一个计算属性,让其返回过滤后的列表即可
- 为了避免渲染本应该隐藏的列表,
- 文档中明确指出,永远不要把 v-if 和 v-for 同时用在同一个元素上面,显示这是不可行的
- 源码里面关于代码生成的部分,能够清晰得分看到是先出来 v-if 还是 v-for 顺序上 vue2 和 vue3 是相反的,但是不管怎么样,不能讲两个放在一起使用
简述 vue 生命周期
- 每个 vue 组件实例被创建后都会经过一系列初始化步骤,比如,它需要数据观测,模板编译,挂载实例到 dom 上,以及数据变化时的更新 dom,这个过程中会运行叫做生命周期的钩子函数,以便用户在特定时期添加自己的代码,
- vue 生命周期总共可以分为 8 个阶段,创建前后,挂在前后,更新前后,卸载(销毁)前后,以及特殊场景的生命周期,vue3 中新增了三个用于调试和服务端渲染场景
生命周期 activated activated keep-alive 缓存的组件激活时,
deactivated deactivated keep-alive 缓存的组件停用时调用的
errorCaptured errorCaptured 捕获一个来自子孙组件的错误时被调用
----------- renderTracked 调试钩子,响应式依赖被收集时调用的
----------- renderTriggered 调试钩子,响应式依赖被触发时调用的
----------- serverPrefetch ssr only 组件实例在服务器上被渲染前调用
beforeCreate :通常用于插件开发中执行一些初始化任务,
created:组件初始化完毕,可以访问各种数据,获取接口数据等,
mounted:dom 已创建,可以进行获取访问数据和 dom 元素,访问子组件,
beforeUpdate:此时 view 层还未更新,更新后,所有状态已是最新,
beforeunmounted:实例被销毁前调用,可用于一些定时器或者订阅的取消,
unmounted:销毁一个实例,可清理它与其他实例的连接,解绑它的全部指令及事件,
追问:setup 和 creatd 谁先执行;
- setup 先执行,setup 中已经创建了组件实例,creatd 是创建之后,
- setup 中为什么没有 beforeCreate 和 created,因为
setup 中已经完成了组件实例的创建,所以没有这两个钩子,这两个钩子是专门为 options API 服务的
双向绑定使用和原理
- vue 中双向绑定是一个指令 v-model,可以绑定一个响应式数据到视图,同时视图中的变化能改变该值,
- v-model 是语法糖,默认情况下相当于:value 和 @input 。使用 v-model 可以减少大量的繁琐的代码,提高开发效率
了解 DIFF 算法
- 在新老虚拟 DOM 对比时: ● 首先,对比节点本身,判断是否为同一节点,如果不为相同节点,则删除该节点重新创建节点进行替换 ● 如果为相同节点,进行 patchVnode,判断如何对该节点的子节点进行处理,先判断一方有子节点一方没有子节点的情况(如果新的 children 没有子节点,将旧的子节点移除) ● 比较如果都有子节点,则进行 updateChildren,判断如何对这些新老节点的子节点进行操作(diff 核心)。 ● 匹配时,找到相同的子节点,递归比较子节点 在 diff 中,只对同层的子节点进行比较,放弃跨级的节点比较,使得时间复杂从 O(n3)降低值 O(n),也就是说,只有当新旧 children 都为多个子节点时才需要用核心的 Diff 算法进行同层级比较。
Vue 中 key 的作用
vue 中 key 值的作用可以分为两种情况来考虑:
- 第一种情况是 v-if 中使用 key。由于 Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。因此当使用 v-if 来实现元素切换的时候,如果切换前后含有相同类型的元素,那么这个元素就会被复用。如果是相同的 input 元素,那么切换前后用户的输入不会被清除掉,这样是不符合需求的。因此可以通过使用 key 来唯一的标识一个元素,这个情况下,使用 key 的元素不会被复用。这个时候 key 的作用是用来标识一个独立的元素。
- 第二种情况是 v-for 中使用 key。用 v-for 更新已渲染过的元素列表时,它默认使用“就地复用”的策略。如果数据项的顺序发生了改变,Vue 不会移动 DOM 元素来匹配数据项的顺序,而是简单复用此处的每个元素。因此通过为每个列表项提供一个 key 值,来以便 Vue 跟踪元素的身份,从而高效的实现复用。这个时候 key 的作用是为了高效的更新渲染虚拟 DOM。
- key 是为 Vue 中 vnode 的唯一标记,通过这个 key,diff 操作可以更准确、更快速
- 更准确:因为带 key 就不是就地复用了,在 sameNode 函数 a.key === b.key 对比中可以避免就地复用的情况。所以会更加准确。
- 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快
赞助