2024年前端面试题Vue篇
希望我的解释和答案能起到辅助理解作用
vue2和vue3的区别
- 写法
- 响应式
- vue2的响应式基于object.defineProperty,而vue3则基于proxy对象 ,相比于vue2,vue3的更有优势,有更好的性能,同时还集成了ts,提供了ref,reactive这种响应式api
- diff算法
- vue2的diff算法基于虚拟dom采用双指针的算法以及同级比较,vue3基于proxy和pach flag,引用pach flag判断更新节点,采用proxy跟踪节点变化,提高diff算法的效率
- 打包体积
- vue2的打包体积通常比较大,因为它有很多内置功能和组件,vue3则采用了tree-shaking,有更好的组件化支持,更好的模版编译来优化打包体积,使打包体积更小
ref、torefs、toref
- 作用:将变量声明或者转变成响应式
- 原理:基于proxy和reflect API实现的,使用proxy在对象属性上设置拦截器,实现对属性的访问以及修改的监听和拦截
reactive
- 作用:将一个普通的js对象转换成响应式数据对象
- 原理:基于proxy和reflect API实现的,使用proxy在对象属性上设置拦截器,实现对属性的访问以及修改的监听和拦截
wacth和computed
- wacth是一个监听器,用来监视一个属性的变化,每次变化的时候执行一个回调函数,有deep属性来决定是否开启深度监听,immediate来决定是否立即执行
- computed是一个计算属性,适用于那些需要计算值,并且储存值的场景,比如商品计算总价
effect
也是一个响应式api,用于追踪响应式依赖项
用法:
import {
reactive, effect } from 'vue';
const state = reactive({
count: 0,
});
// 创建一个 effect 函数
const countEffect = effect(() => {
console.log(`Count is: ${
state.count}`);
});
// 修改状态
state.count++; // 触发 countEffect 函数重新执行
// 输出:Count is: 1
nextTick
- 作用:确保在下一次dom更新周期之前,所有的数据都更新完成
- 原理:基于event loop机制。当执行nexttick函数的时候,vue.js会将回调函数加入到一个队列中,并使用promise在下一次event loop来执行该函数
- 理解:就是在数据发生变化的时候,vue不会立刻去更新dom,而是把这些要修改的数据放在一个异步队列里,一直修改一直进行异步操作,所以我们直接去拿值拿的不是最新的值,所以这里我们可以使用NextTick,它有一个更新机制,可以让我们更快的读取最新的dom结构
异步组件
1.使用defineAsynccomponents函数:
import {
defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
)
export default {
components: {
AsyncComponent
}
}
2.使用组件:
<template>
<div>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</div>
</template>
<script>
import {
defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
)
export default {
components: {
AsyncComponent
}
}
</script>
pinia
- pinia和vuex一样是一个全局状态管理库
- 有三个核心:
- state
- getters
- actions
.use()
作用:安装插件,在应用程序启动的时候添加全局的功能,并为插件提供一个统一
的安装入口
h()函数
- 作用:用来创建虚拟dom节点
- 使用:接受三个参数:标签名、属性对象和子节点数组,然后返回一个描述了对应虚拟 DOM 节点的 JavaScript 对象。
import {
h } from 'vue'
const vnode = h('div', {
id: 'app' }, [
h('h1', null, 'Hello, Vue 3!'),
h('p', null, 'This is a paragraph.')
])
render()函数
- 作用:将虚拟dom节点变成真实dom节点
- 使用:
import {
h } from 'vue'
export default {
props: {
message: {
type: String,
required: true
}
},
render() {
return h('div', [
h('h1', this.message),
h('p', 'This is a paragraph.')
])
}
}
keep-alive
- 概念:是一个抽象组件,将动态组件缓存起来,避免销毁和重复渲染
- 原理:基于vue的虚拟dom和生命周期,当一个动态组件被keep-alive包裹的时候,keep-alive会将这个组件的vnode也就是虚拟dom节点缓存起来,并在组件的deactiveted中销毁缓存的组件,当组件再次渲染的时候,keep-alive会从name属性拿到对应的vnode,把它渲染到页面上,这样就避免了重复渲染和销毁,提高了应用性能
插槽
插槽就是一个传递内容的机制,它允许自定义组件内的内容,提高了组件灵活性
- 默认插槽
- 具名插槽