1、v-model是谁的语法糖
答:v-model是props + events(双向绑定)的封装,在Vue2和Vue3中略有不同:
- Vue2中一般是用来绑定在输入框
input上,等价于:value + @input,子组件中通过$emit('input', newValue)通知父组件进行更新。 - Vue3中
<Child v-model="value" />等价于<Child :modelValue="value" @update:modelValue="value = $event" />。modelValue是默认的 prop 名,update:modelValue是默认的事件名
注:Vue3中支持一个组件上绑定多个v-model:
<Child v-model:content="content" v-model:title="title" />
// 等价于
<Child
:title="title"
@update:title="title = $event"
:content="content"
@update:content="content = $event"
/>
// 子组件
defineProps(['title','content'])
const emit = defineEmits<{
(e: 'update:title', value: string): void;
(e: 'update:content', value: string): void;
}>();
2、keep-alive如何实现缓存组建
答:<keep-alive>是Vue内置的一个抽象组件,用于缓存组件的状态,避免组件频繁销毁与重建,从而提升性能。它常用于切换的组件场景,比如:标签页(Tab)、页面切换等。
<template>
<keep-alive>
<component :is="currentView" />
</keep-alive>
</template>
<script setup>
import A from './A.vue';
import B from './B.vue';
import { ref } from 'vue';
const currentView = ref('A'); // 切换为 B 就缓存 A 组件
</script>
- 搭配
router-view使用(页面缓存);
<!-- Vue Router 默认不会缓存页面,必须用 <keep-alive> 包裹 router-view 才能缓存页面组件。 -->
<template>
<keep-alive>
<router-view v-slot="{ Component }">
<component :is="Component" />
</router-view>
</keep-alive>
</template>
- 搭配 include / exclude 控制缓存范围;
<!-- 只缓存A、B组件 (A、B是组件的name)-->
<keep-alive include="A,B">
<component :is="currentView" />
</keep-alive>
- 生命周期感知:
activated / deactivated,缓存组件不会触发mounted 和 unmounted
// 初次渲染时,会执行 onMounted 生命周期,也会执行 onActivated,但是缓存后就不执行 onMounted了,会执行onActivated
<script setup>
onActivated(() => {
console.log('组件被激活(缓存中恢复)');
});
onDeactivated(() => {
console.log('组件被缓存(离开但不卸载)');
});
</script>
3、Vue 生命周期
- Vue3 生命周期:
setup() → onBeforeMount() → onMounted() → onBeforeUpdate() → onUpdated() → onBeforeUnmount() → onUnmounted(); - Vue2 生命周期:
生命周期:beforeCreate → created → beforeMount → mounted -> beforeUpdate → updated -> beforeDestroy → destroyed;
父子组件嵌套时:
- 同步导入子组件时生命周期:父组件的
setup()-> 父组件(onBeforeMount)-> 子组件setup()-> 子组件(onBeforeMount)-> 子组件(onMounted)-> 父组件(onMounted) - 异步导入子组件时生命周期:父组件的
setup()-> 父组件(onBeforeMount)-> 父组件(onMounted)-> 子组件setup()-> 子组件(onBeforeMount)-> 子组件(onMounted)
4、vue2和vue3 的区别
答:Vue2 和 Vue3 在语法、性能、架构设计、API 风格等方面都有显著的区别。
- 响应式系统原理
Vue2通过Object.defineProperty()实现,Vue3使用Proxy实现; - Vue3支持组合式API,使其更适合复用和
TS支持,适合大型项目结构化拆分; - 生命周期的不同:
- Vue2 生命周期
beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed - Vue3 生命周期
setup -> onBeforeMount-> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted
- Vue2 生命周期
- Vue3 独有的一些新特性:
- Fragment:可以有多个根节点组件
- Teleport(传送门):组件内容可渲染到 DOM 任意位置
- to:可以是标签上的 id,或者 body,需要是已经存在的节点
- 会渲染到
<div id="custom-modal-root"></div>标签内
<div id="custom-modal-root"></div> <teleport to="#custom-modal-root"> <div>可以传送到任意节点渲染</div> </teleport> - v-model 的多绑定支持
- Suspense:异步组件更优雅加载
- 用来出来异步组件加载的状态(如 loading、error)的内置组件,非常适合包裹
defineAsyncComponent或使用setup()中的异步逻辑。
- 用来出来异步组件加载的状态(如 loading、error)的内置组件,非常适合包裹
<Suspense> <template #default> <UserCard /> </template> <template #fallback> <div>加载用户数据中...</div> </template> </Suspense>- 更好的
TypeScript支持 script setup语法糖defineProps / defineEmits简化逻辑reactive, ref, computed, watch全部可组合式使用- 增加了
watchEffect
- 性能方面
- Vue3 使用 静态提升、
Patch flag优化虚拟DOM diff过程; - 更小打包体积
- 快速首次渲染和更新
- Vue3 使用 静态提升、
- Vite 支持 Vue3 更友好,Vue3 可以使用 @vue/runtime-core 创建自定义渲染器