vue常见面试题(1)(结合vue2+vue3)

293 阅读5分钟

vue组件之间通信方式

父子之间

props,emit,emit, attrs,ref,$parent

兄弟之间

vuex, parent,parent,root,eventbus

隔代组件之间

provide/inject, eventbus,vuex

v-for和v-if哪个优先级更高

实践总结

在vue的官方文档中明确说明在实践中不应该将v-if和v-for放在一起使用

结论

在vue2中,v-for的优先级更高, 如果你在vue2中将v-if和v-for同时放在一个标签中使用,会发现输出的渲染函数时先执行循环, 然后再再循环中进行判断, 即使那你需要的只是循环中的一小部分数据,也需要再每次重新渲染的时候便利整个列表, 这是很浪费性能的

在vue3中,v-if优先级更高, 如果你在vue3中将v-if和v-for同时放在一个标签中使用,在v-if中调用了v-for遍历出来的变量会报错, 所以证明v-if优先级更高

实践中的需求以及解决方案

只需要渲染列表中的部分数据:解决方案, 定义一个计算属性, 返回过滤后的列表数据即可

避免渲染本身不需要显示的列表数据: 解决方案, 将v-if放在列表容器上或者在上一层加上template标签

源码层面

从源码中可以看出,在vue编译模板的时候, vue2中是先判断v-for指令, 因此v-for的优先级更高, 而在vue3中, 是先判断的v-if指令, 所以v-if优先级更高

简述vue的生命周期以及每个周期所做的事情

每个vue组件实例被创建后都会经历一系列的初始化过程, 如数据观测, 模板编译,挂载实例到dom以及数据变化时及时更新到dom上,这个过程中会运行生命周期的钩子,方便我们在特定的时机有机会添加我们的代码

beforeCreate: 组件实例创建之初,此时还不可访问数据等

created: 组件初始化完成, 此时可以访问data,获取接口数据等

beforeMount: 组件开始挂载, 此时还不可访问dom元素

mounted: 组件挂载完毕, 可以访问dom元素, 可以访问子组件

beforeUpdate: 组件更新前, 此时可以获取组件更新前的状态

updated: 组件更新完成,更新后所有状态都是最新的

vue2源码中的顺序

image.png

image.png

vue3源码

延申问题(todo):

     setUp和created谁先执行

     setUp中为什么没有beforeCreate和created

说一说vue中双向绑定的使用和原理

vue中的双向绑定是一个指令v-model, 改变绑定的响应式数据,视图也会跟着更新,v-model是一个语法糖,默认是:value和@input,使用v-model可以减少大量的事件处理代码,提高开发效率

v-model通常用在表单项上,也会用在自定义的组件上, 控制数据的输入输出

v-model在input和textarea中是使用常规的值绑定到表单的value上, 在checkbox中可以设置truthy和falsey值为相应的value值, 在radio中则是可以使用label中的值和的value进行比对改变样式, 在select中通过options中的value来设置特殊的值,v-model还可以通过.trim,.lazy,.number等对输入做进一步的限定,在vue3中v-model和.sync运算符很像, 展开时候就是modelValue和update:mmodelValue的形式, 还可以通过使用v-model:foo和v-model:bar的形式实现多个绑定

vue中如何扩展一个组件

常见方法:mixins,slots,extends(vue3)

vue3中的方法:compositionApi

混⼊mixins是分发 Vue 组件中可复⽤功能的⾮常灵活的⽅式。混⼊对象可以包含任意组件选项。当组件使⽤ 混⼊对象时,所有混⼊对象的选项将被混⼊该组件本身的选项。

插槽slot主要用于vue中组件的内容分发, 也用于组件扩展

组件选项中还有⼀个不太常⽤的选项extends,也可以起到扩展组件的⽬的

extenss扩展对象注意事项: const myextends = { methods: { dosomething(){} } }

  • 组件扩展:做数组项设置到extends选项,仅作⽤于当前组件
  • 跟混⼊的不同是它只能扩展单个对象
  • 另外如果和混⼊发⽣冲突,该选项优先级较⾼,优先起作⽤ const Comp = { extends: myextends }

混⼊的数据和⽅法不能明确判断来源且可能和当前组件内变量产⽣命名冲突,vue3中引⼊的composition api,可以很好解决这些问题,利⽤独⽴出来的响应式模块可以很⽅便的编写独⽴逻辑并提供响应式的数据, 然后在setup选项中组合使⽤,增强代码的可读性和维护性

⼦组件可以直接改变⽗组件的数据么,说明原因

  1. 所有的 prop 都使得其⽗⼦之间形成了⼀个单向下⾏绑定:⽗级 prop 的更新会向下流动到⼦组件中,但是反 过来则不⾏。这样会防⽌从⼦组件意外变更⽗级组件的状态,从⽽导致你的应⽤的数据流向难以理解。另外, 每次⽗级组件发⽣变更时,⼦组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在⼀个⼦组件内 部改变 prop。如果你这样做了,Vue 会在浏览器控制台中发出警告。

  2. 实际开发过程中有两个场景会想要修改⼀个属性:

    • 这个 prop ⽤来传递⼀个初始值;这个⼦组件接下来希望将其作为⼀个本地的 prop 数据来使⽤。在这 种情况下,最好定义⼀个本地的 data,并将这个 prop ⽤作其初始值:

    • 这个 prop ⽤来传递⼀个初始值;这个⼦组件接下来希望将其作为⼀个本地的 prop 数据来使⽤。在这 种情况下,最好定义⼀个本地的 data,并将这个 prop ⽤作其初始值:

  3. 实践中如果确实想要改变⽗组件属性应该emit⼀个事件让⽗组件去做这个变更。