Vue3 前端面试常见 20 道面试题总结(含详细代码解析)
1. Vue3 中 Composition API 的优势是什么?
答:
Vue3 中引入了 Composition API,使得代码组织更加灵活,解决了 Vue2 中基于 Options API 的一些问题,如:
- 逻辑复用性差:Vue2 中的逻辑复用通过 mixins 或者 slots 等方式,代码可维护性较差。
- 组件中有很多逻辑时,数据和方法会分散在不同的地方,不易管理。
优势:
- 使逻辑复用变得更加简单,
setup()
函数中封装逻辑,多个组件可以复用。 - 提供了更强的类型推导支持,特别适用于 TypeScript。
- 使得代码更加结构化和模块化,特别是当组件变得复杂时。
// Composition API 示例
import { ref, reactive, computed, watch } from 'vue'
export default {
setup() {
const count = ref(0)
const state = reactive({ message: 'Hello Vue3' })
const increment = () => {
count.value++
}
// computed 示例
const doubleCount = computed(() => count.value * 2)
// watch 示例
watch(count, (newValue, oldValue) => {
console.log('count changed from', oldValue, 'to', newValue)
})
return {
count,
state,
increment,
doubleCount
}
}
}
2. Vue3 和 Vue2 的响应式系统有何区别?
答:
Vue3 的响应式系统基于 Proxy,而 Vue2 是基于 Object.defineProperty。这带来了以下区别:
- 性能:Vue3 在处理大量的数据和复杂的嵌套对象时性能更优,因为 Proxy 可以直接操作对象的所有属性,而 Vue2 需要为每个属性单独定义 getter 和 setter。
- 支持动态添加/删除属性:Vue3 的 Proxy 可以检测到动态添加或删除的属性,而 Vue2 在这方面有一些局限。
- API 的简化:Vue3 使用了
ref()
和reactive()
等简化的 API。
// Vue3 响应式示例
import { reactive, toRefs } from 'vue'
export default {
setup() {
const state = reactive({
count: 0,
name: 'Vue3'
})
return {
...toRefs(state) // 用于解包响应式对象,避免引用错误
}
}
}
3. Vue3 中如何创建一个动态组件?
答:
动态组件可以使用 component
标签和 v-bind
或 v-model
来动态加载不同的组件。
<template>
<component :is="currentComponent" />
</template>
<script setup>
import { ref } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
const currentComponent = ref(ComponentA)
// 动态切换组件
setTimeout(() => {
currentComponent.value = ComponentB
}, 3000)
</script>
4. Vue3 如何实现父子组件通信?
答:
- 父组件向子组件传递数据:使用
props
。 - 子组件向父组件传递数据:使用
emit
事件。
<!-- 父组件 -->
<template>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const parentMessage = ref('Hello from Parent')
const handleChildEvent = (data) => {
console.log('Received from child:', data)
}
</script>
<!-- 子组件 -->
<template>
<button @click="sendToParent">Send to Parent</button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
defineProps(['message'])
const emit = defineEmits()
const sendToParent = () => {
emit('childEvent', 'Hello from Child')
}
</script>
5. Vue3 中如何使用 v-model
?
答:
在 Vue3 中,v-model
默认绑定 value
,并且可以通过 modelValue
修改。
<!-- 父组件 -->
<template>
<ChildComponent v-model="message" />
</template>
<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'
const message = ref('Hello World')
</script>
<!-- 子组件 -->
<template>
<input v-model="modelValue" />
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
const emit = defineEmits()
// 当 input 变化时同步 modelValue
watch(() => props.modelValue, (newValue) => {
emit('update:modelValue', newValue)
})
</script>
6. Vue3 中如何实现懒加载组件?
答:
使用 Vue 的异步组件功能来实现懒加载。通过 defineAsyncComponent
或 import()
实现。
import { defineAsyncComponent } from 'vue'
export default {
components: {
AsyncComponent: defineAsyncComponent(() => import('./AsyncComponent.vue'))
}
}
7. Vue3 如何使用 watch
和 watchEffect
?
答:
watch
用于观察指定的数据源,并在数据变化时执行副作用。watchEffect
会立即执行并自动跟踪响应式依赖。
import { ref, watch, watchEffect } from 'vue'
const count = ref(0)
watch(count, (newValue, oldValue) => {
console.log('count changed from', oldValue, 'to', newValue)
})
watchEffect(() => {
console.log('This is tracked:', count.value)
})
setTimeout(() => {
count.value = 5
}, 2000)
8. 如何在 Vue3 中使用 provide
和 inject
?
答:
provide
和inject
用于跨组件层级传递数据,解决了 Vue2 中的 “prop drilling” 问题。
// 父组件
<template>
<Child />
</template>
<script setup>
import { provide } from 'vue'
provide('message', 'Hello from Parent')
</script>
<!-- 子组件 -->
<template>
<div>{{ message }}</div>
</template>
<script setup>
import { inject } from 'vue'
const message = inject('message')
</script>
9. Vue3 中如何创建一个自定义指令?
答:
可以使用 app.directive()
来全局注册自定义指令,也可以使用 v-bind
动态传递。
// 全局注册
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.directive('focus', {
mounted(el) {
el.focus()
}
})
app.mount('#app')
10. Vue3 中如何使用 teleport
进行跨层级渲染?
答:teleport
用于将组件的内容渲染到 DOM 树的不同位置。
<template>
<teleport to="body">
<div class="modal">
<p>This is a modal</p>
</div>
</teleport>
</template>
11. 如何在 Vue3 中处理异步操作?
答:
Vue3 推荐使用 async
和 await
来处理异步操作,配合 watchEffect
或生命周期钩子。
import { ref, onMounted } from 'vue'
const data = ref(null)
onMounted(async () => {
const response = await fetch('https://api.example.com/data')
data.value = await response.json()
})
12. Vue3 的 Suspense
组件如何使用?
答:Suspense
组件用于等待异步组件的加载结果。
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<p>Loading...</p>
</template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'))
</script>
13. 如何在 Vue3 中使用 ref
和 reactive
的区别?
答:
ref
适用于原始类型(如字符串、数字),它会返回一个对象,包含value
属性。reactive
适用于对象或数组,返回的是响应式对象。
import { ref, reactive } from 'vue'
const count = ref(0)
const state = reactive({ count: 0 })
// 可以直接修改
count.value++
state.count++
---
#### **14. Vue3 的 `v-bind` 和 `v-model` 区别?**
**答**:
- `v-bind` 用于绑定一个属性到某个组件。
- `v-model` 用于双向绑定,默认绑定 `value` 属性。
---
#### **15. Vue3 中如何实现状态管理?**
**答**:
Vue3 中的状态管理可以使用 **Pinia**,它是 Vue 官方推荐的状态管理库。
```javascript
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
16. 如何在 Vue3 中使用 mixins?
答:
Vue3 支持 mixins,虽然 Composition API 更推荐,但还是可以使用 mixins。
const myMixin = {
data() {
return {
message: 'Hello'
}
},
methods: {
greet() {
console.log(this.message)
}
}
}
17. Vue3 如何处理动态路由?
答:
使用 Vue Router 来处理动态路由,使用 :param
来动态匹配 URL。
const routes = [
{
path: '/user/:id',
component: User
}
]
18. Vue3 中如何调试性能问题?
答:
Vue3 提供了 Vue DevTools,可以用来分析组件性能,查看响应式数据流,以及查看生命周期。
19. Vue3 中如何使用 scoped slots?
答:
Vue3 中使用 v-slot
来替代 scoped slots 语法。
<template #default="{ item }">
<p>{{ item.name }}</p>
</template>
20. 如何在 Vue3 中优化性能?
答:
- 使用
keep-alive
缓存组件。 - 使用异步组件和
Suspense
。 - 避免不必要的 reactivity 和 watchers。
这些问题涵盖了 Vue3 中最常见的概念与技巧,能够帮助前端开发者在面试中充分展示自己的能力。
发表回复