1. 如何在 Vue 3 中使用 defineAsyncComponent
实现异步组件加载?
defineAsyncComponent
是 Vue 3 提供的工具,用于按需加载组件,优化性能,特别是在大型应用中。
使用方法:
- 基础用法
直接导入组件时,通过defineAsyncComponent
定义异步加载逻辑。
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'));
export default {
components: {
AsyncComponent
}
};
- 高级用法:添加加载状态和超时处理
可以通过选项对象配置加载组件、错误组件、超时时间等。
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
loadingComponent: LoadingComponent, // 加载中组件
errorComponent: ErrorComponent, // 加载失败组件
delay: 200, // 延迟显示加载组件
timeout: 3000 // 超时
});
- 结合
Suspense
使用
在异步加载组件时,配合Suspense
提供优雅的加载体验。
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<LoadingComponent />
</template>
</Suspense>
</template>
<script>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'));
export default {
components: {
AsyncComponent,
LoadingComponent
}
};
</script>
2. 如何在 Vue 3 中实现一个复杂的表单验证和提交逻辑?
基本思路:
- 使用
v-model
双向绑定表单数据。 - 配合
ref
管理表单状态。 - 使用
watch
或computed
实现实时验证。 - 提交时进行集中校验。
示例代码:
<template>
<form @submit.prevent="handleSubmit">
<div>
<label for="name">Name:</label>
<input id="name" v-model="form.name" @blur="validateName" />
<span>{{ errors.name }}</span>
</div>
<div>
<label for="email">Email:</label>
<input id="email" v-model="form.email" @blur="validateEmail" />
<span>{{ errors.email }}</span>
</div>
<button type="submit" :disabled="isSubmitting">Submit</button>
</form>
</template>
<script>
import { reactive, ref, computed } from 'vue';
export default {
setup() {
const form = reactive({
name: '',
email: ''
});
const errors = reactive({
name: '',
email: ''
});
const isSubmitting = ref(false);
const validateName = () => {
errors.name = form.name ? '' : 'Name is required';
};
const validateEmail = () => {
errors.email = /\S+@\S+\.\S+/.test(form.email) ? '' : 'Invalid email';
};
const handleSubmit = async () => {
validateName();
validateEmail();
if (!errors.name && !errors.email) {
isSubmitting.value = true;
// 模拟提交逻辑
await new Promise(resolve => setTimeout(resolve, 1000));
alert('Form submitted!');
isSubmitting.value = false;
}
};
return {
form,
errors,
isSubmitting,
validateName,
validateEmail,
handleSubmit
};
}
};
</script>
使用工具库:
可结合 VeeValidate
或 Yup
实现更强大的表单验证逻辑。
3. 如果要实现一个 Vue 3 的弹窗组件,你会如何设计?
基本思路:
- 支持动态内容:通过
slot
插入弹窗内容。 - 控制显示/隐藏:通过
v-if
或v-show
控制弹窗的渲染。 - 事件传递:提供关闭回调和自定义事件。
- 可复用性:定义为全局或局部组件。
实现代码:
<template>
<div v-if="isVisible" class="modal-overlay" @click="close">
<div class="modal-content" @click.stop>
<slot></slot>
<button @click="close">Close</button>
</div>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
props: {
visible: {
type: Boolean,
default: false
}
},
emits: ['update:visible'],
setup(props, { emit }) {
const isVisible = ref(props.visible);
const close = () => {
isVisible.value = false;
emit('update:visible', false);
};
return { isVisible, close };
}
};
</script>
<style>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: relative;
margin: auto;
padding: 20px;
background: #fff;
}
</style>
使用示例:
<template>
<button @click="showModal = true">Show Modal</button>
<Modal v-model:visible="showModal">
<h1>Hello Modal</h1>
</Modal>
</template>
<script>
import Modal from './Modal.vue';
export default {
components: { Modal },
data() {
return { showModal: false };
}
};
</script>
4. 什么是 Vue 3 的 Tree-shaking 特性?有什么作用?
定义:
Tree-shaking 是一种优化技术,可以移除未使用的代码。Vue 3 使用基于 ES Module 的编译,使得未用到的模块在打包时被移除。
作用:
- 减小打包体积,提高性能。
- 使 Vue 更适合现代前端框架的开发需求。
实现原理:
- Vue 3 的模块化设计将功能(如
reactive
、ref
)拆分为独立的模块。 - 打包工具(如 Webpack、Vite)会通过静态分析,移除未使用的部分。
5. Vue 3 中的 Composition API 与 Vue 2.x 的 Options API 有什么区别?
特性 | Composition API | Options API |
---|---|---|
语法风格 | 函数式编程 | 配置式编程 |
逻辑复用 | 通过组合函数(setup )复用 | 使用混入(Mixin),容易命名冲突 |
代码组织 | 可将逻辑集中到一起,便于维护 | 逻辑分散在不同的生命周期钩子 |
TypeScript 支持 | 原生支持 TypeScript,更易于类型推断 | TypeScript 支持较弱 |
学习曲线 | 对于复杂逻辑较高,但更灵活 | 更适合初学者,简单直观 |
6. 你如何在 Vue 3 中管理全局状态?使用了哪些工具和方法?
方法:
-
reactive
和provide/inject
直接使用 Vue 3 的reactive
和provide/inject
组合管理状态。 -
Pinia(推荐)
Vue 官方推荐的状态管理工具,轻量、类型安全。
import { defineStore } from 'pinia';
export const useStore = defineStore('main', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
}
}
});
- Vuex(传统方式)
适合复杂应用,但与 Vue 3 的组合式 API 配合不如 Pinia。
7. Vue 2 和 Vue 3 有哪些区别?Vue 3 有哪些更新?
特性 | Vue 2 | Vue 3 |
---|---|---|
性能 | 使用 defineProperty 进行响应式 | 使用 Proxy 提升性能和灵活性 |
API 风格 | Options API | Composition API,支持逻辑复用 |
组件渲染 | 不支持 Fragment | 支持 Fragment,减少无意义的 DOM 节点 |
状态管理 | 推荐 Vuex | 推荐 Pinia |
优化 | 无 Tree-shaking 支持 | Tree-shaking 支持,减小打包体积 |
8. Vue 3 中的 Fragment 是什么?有什么作用?
定义:
Fragment 是一种无包装节点的虚拟 DOM 节点,允许组件返回多个根节点。
作用:
- 减少多余的 DOM 层级。
- 提高性能,优化 DOM 结构。
示例代码:
<template>
<h1>Title</h1>
<p>Paragraph</p>
</template>
9. Vue 3 中的 Suspense 组件有什么作用?如何使用它来处理异步组件?
定义:
Suspense
是 Vue 3 提供的异步组件处理机制,可以在加载异步组件时显示占位内容。
使用方法:
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<Loading />
</template>
</Suspense>
</template>
10. Vue 3 中的 Vue Composition API 是什么?
定义:
Composition API
是 Vue 3 引入的一种新的组件逻辑组织方式,可以通过函数集中管理组件逻辑。
11. 为什么 Vue 3 中使用 Proxy API 替代了 defineProperty API?
原因:
Proxy
能直接代理整个对象,而defineProperty
需要逐个属性绑定。- 支持数组、动态添加属性等。
12. Vue 3 性能提升主要体现在哪些方面?
- 使用
Proxy
提升响应式性能。 - 支持 Tree-shaking 减小打包体积。
- Fragment 减少 DOM 节点。
- 编译优化生成更高效的代码。
13. Vue 3 的设计目标是什么?在设计过程中做了哪些优化?
- 目标:更小、更快、更强。
- 优化:改用 Proxy、引入 Composition API、支持 Tree-shaking。
14. Vue 3 中的 watch 和 watchEffect 有什么区别?如何选择使用它们?
特性 | watch | watchEffect |
---|---|---|
依赖声明 | 需要显式声明 | 自动追踪依赖 |
用途 | 适合处理特定数据变化 | 适合处理直接副作用逻辑 |
15. Vue 3 使用的 DIFF 算法相比 Vue 2 的双端比对有什么优点?
- 使用静态标记优化,只对动态部分做 DIFF。
- 提升了运行时性能,减少不必要的更新。