Vue面试题-01
前言
马上要秋招了,搜集整理了一些Vue面试题,包括组件、指令、API等相关内容,巩固基础😎秋招冲冲冲!!!本篇包括:
✅ webpack和vite的对比
✅ v-if和v-show的区别
✅ 绑定class的数组用法
✅ 组件中data为什么是函数
✅ 生命周期
Webpack 和 Vite对比
vite凭什么比webpack快
webpack启动需要打包
webpack dev serve
在启动时,会把所有的包都build
一遍,从入口文件起索引整个项目的文件,编译成一个或多个js文件,不管模块是否被执行,都会被打包到bundler里。随着项目的复杂程度上升,模块增加,打包后的bundler也会越来越大,打包速度会越来越慢。即项目越复杂,启动时间越来越长。
Vite在启动时不需要打包,不需要拆分模块的依赖,不需要编译,启动速度非常快。
由于现代浏览器本身就支持ES Module,会自动向依赖的Module发出请求。vite充分利用这一点,将开发环境下的模块文件,就作为浏览器要执行的文件,而不是像webpack那样进行打包合并。
vite 请求哪个模块再对该模块进行实时编译 webpack全部编译
当浏览器请求某个模块时,再根据需要对模块内容进行编译。这种按需动态编译的方式,极大的缩减了编译时间,项目越复杂、模块越多,vite的优势越明显。 在HMR方面,当改动了一个模块后,仅需让浏览器重新请求该模块即可,不像webpack那样需要把该模块的相关依赖模块全部编译一次,效率更高。 当需要打包到生产环境时,vite使用传统的rollup进行打包,因此,vite的主要优势在开发阶段。另外,由于vite利用的是ES Module,因此在代码中不可以使用CommonJS
在底层实现上,vite是基于esbuild预构建的,esbuild使用go语言编写,比js编写的打包器预构建快10-100倍,js的操作一般是毫秒级,但go达到了纳秒级
参考链接:
v-if 和 v-show的区别
首先,v-show
只是 CSS 级别的 display: none;
和 display: block;
之间的切换,而 v-if
决定是否会选择代码块的内容(或组件)。
当需要非常频繁地切换时,使用 v-show
;一次性渲染完(运行时条件很少改变),使用 v-if
。
使用 v-if
在性能优化上有什么经验?
因为当 v-if="false"
时,内部组件是不会渲染的,所以在特定条件才渲染部分组件(或内容)时,可以先将条件设置为 false
,需要时(或异步,比如 $nextTick)再设置为 true
,这样可以优先渲染重要的其它内容,合理利用,可以进行性能优化。
v-if
是“真正”的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。相比之下,
v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。当
v-if
与v-for
一起使用时,v-if
具有比v-for
更高的优先级。不推荐v-if和v-for一起使用
参考链接:
绑定 class 的数组用法
首先是基本的对象用法,传给 :class
(v-bind:class
的简写) 一个对象,以动态地切换 class:
1 | <template> |
我们也可以在这里绑定一个返回对象的计算属性。这是一个常用且强大的模式:
1 | <template> |
绑定 class 的对象用法能满足大部分业务需求,不过,在复杂的场景下,会用到数组,数组中可以有对象、三元表达式
1 | <div :class="[activeClass, errorClass]"></div> |
下面给出一个更为复杂的例子,iView的Button组件,数组里,可以是固定的值,还有动态值(对象)的混合。
1 | <template> |
参考链接:
组件中data为什么是函数
组件是用来复用的。 在Vue中,组件就相当于积木,我们需要用这些积木来搭建我们所预期的结构。在搭建过程中,会重复使用某一类别的积木以完成功能。我们希望在使用组件时,data
数据是相互隔离,互不影响的。 组件每复用一次,data
数据就应该被复制一次,之后,当某一处复用的地方组件内data
数据被改变时,其他复用地方组件的data
数据不受影响,就需要通过data函数返回一个对象作为组件的状态。
如果我们把组件的data写成对象形式,这些实例用的是同一个构造函数,由于JavaScript的特性,js里对象是引用关系,作用域没有隔离 ,所有的组件实例共用了一个data,就会造成一个变了全都会变(牵一发而动全身)的结果。不能因为将一块圆锥体积木放置在屋顶位置,就将其他用到圆锥体的地方都重置在屋顶。
当我们将组件中的data
写成一个函数,数据以函数返回值形式定义 ,这样每复用一次组件,就会返回一份新的data
,拥有自己的作用域,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据 。
vue每次会通过组件创建出一个构造函数,每个实例都是通过这个构造函数new出来的。
如果data是一个对象,将这个对象放到这个放到原型上去
1 | function VueComponent(){} |
将data改为一个函数
1 | // 这样就可以保证每个组件调用data返回一个全新的对象,和外部没有关系 |
参考链接:
生命周期
Vue3 生命周期 主要有 8 个阶段:
-
创建前 / 后(beforeCreate / created):在 beforeCreate 阶段,Vue 实例的挂载元素 el 和数据对象 data 都为 undefined,还未初始化。在 created 阶段,Vue 实例的数据对象 data 有了,el 还没有。
-
载入前 / 后(beforeMount / mounted):在 beforeMount 阶段,Vue 实例的 $el 和 data 都初始化了,但还是挂载之前为虚拟的 DOM 节点,data 尚未替换。在 mounted 阶段,Vue 实例挂载完成,data 成功渲染。
-
更新前 / 后(beforeUpdate / updated):当 data 变化时,会触发 beforeUpdate 和 updated 方法。这两个不常用,且不推荐使用。
-
销毁前 / 后(beforeDestroy / destroyed):beforeDestroy 是在 Vue 实例销毁前触发,一般在这里要通过 removeEventListener 解除手动绑定的事件。实例销毁后,触发 destroyed。
所有生命周期钩子的
this
上下文将自动绑定至实例中,因此你可以访问 data、computed 和 methods。这意味着你不应该使用箭头函数来定义一个生命周期方法 (例如created: () => this.fetchTodos()
)。因为箭头函数绑定了父级上下文,所以this
不会指向预期的组件实例,并且this.fetchTodos
将会是 undefined。
相关文章
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=30t04w2kn86ck