面试题答案
一键面试1. 项目初始化与环境准备
- 安装 Vue 3:
确保项目的
package.json
中,将vue
版本更新为 Vue 3 相关版本,例如^3.0.0
。然后执行npm install
或yarn install
安装依赖。 - 构建工具升级:
如果项目使用
webpack
,需确保webpack
及相关loader
(如vue - loader
)版本支持 Vue 3。对于vue - cli
创建的项目,可使用vue - cli
最新版本来初始化新项目结构,再将原项目文件逐步迁移进去。
2. Options API 逻辑迁移到 Composition API
- 组件转换:
- 数据属性:
在 Options API 中,数据定义在
data
函数里。在 Composition API 中,使用reactive
或ref
来定义响应式数据。例如:
- 数据属性:
在 Options API 中,数据定义在
// Options API
export default {
data() {
return {
count: 0
}
}
}
// Composition API
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
return {
count
};
}
}
- **计算属性**:
Options API 中的计算属性在 computed
对象中定义。在 Composition API 中,使用 computed
函数。例如:
// Options API
export default {
data() {
return {
count: 1
}
},
computed: {
doubleCount() {
return this.count * 2;
}
}
}
// Composition API
import { ref, computed } from 'vue';
export default {
setup() {
const count = ref(1);
const doubleCount = computed(() => count.value * 2);
return {
count,
doubleCount
};
}
}
- **方法**:
Options API 中的方法定义在 methods
对象里。在 Composition API 中,直接在 setup
函数中定义函数并返回。例如:
// Options API
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++;
}
}
}
// Composition API
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
const increment = () => {
count.value++;
};
return {
count,
increment
};
}
}
- **生命周期钩子**:
Options API 中的生命周期钩子直接在组件对象中定义,如 created
、mounted
等。在 Composition API 中,使用对应的生命周期函数。例如:
// Options API
export default {
created() {
console.log('Component created');
}
}
// Composition API
import { onBeforeMount } from 'vue';
export default {
setup() {
onBeforeMount(() => {
console.log('Component created');
});
}
}
- 逻辑拆分与复用:
- 提取逻辑到独立函数:
可以将相关逻辑提取到独立的函数中,在
setup
函数中调用。例如,对于一个获取用户信息的逻辑:
- 提取逻辑到独立函数:
可以将相关逻辑提取到独立的函数中,在
// userInfo.js
import { ref, onMounted } from 'vue';
export const useUserInfo = () => {
const userInfo = ref(null);
onMounted(() => {
// 模拟异步获取用户信息
setTimeout(() => {
userInfo.value = { name: 'John' };
}, 1000);
});
return {
userInfo
};
};
// 组件中使用
import { setup } from 'vue';
import { useUserInfo } from './userInfo.js';
export default {
setup() {
const { userInfo } = useUserInfo();
return {
userInfo
};
}
}
3. 处理兼容性问题
- API 兼容性:
- 废弃 API:
Vue 3 废弃了一些 Vue 2 的 API,如
this.$on
、this.$off
、this.$once
。对于事件总线功能,Vue 3 推荐使用mitt
或tiny - emitter
等第三方库实现。例如,安装mitt
:npm install mitt
,使用方式如下:
- 废弃 API:
Vue 3 废弃了一些 Vue 2 的 API,如
import mitt from'mitt';
const emitter = mitt();
// 监听事件
emitter.on('eventName', () => {
console.log('Event received');
});
// 触发事件
emitter.emit('eventName');
- **全局 API 变更**:
Vue 3 中全局 API 有变更,如 Vue.component
在 Vue 3 中变为 app.component
。对于创建全局应用实例,Vue 3 使用 createApp
方法。例如:
// Vue 2
import Vue from 'vue';
import App from './App.vue';
new Vue({
render: h => h(App)
}).$mount('#app');
// Vue 3
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.mount('#app');
- 模板语法兼容性:
- v - model 语法:
Vue 3 中
v - model
语法有变化。在 Vue 2 中,v - model
对自定义组件默认绑定value
属性和input
事件。在 Vue 3 中,v - model
绑定modelValue
属性和update:modelValue
事件。例如:
- v - model 语法:
Vue 3 中
<!-- Vue 2 自定义组件 -->
<template>
<input :value="value" @input="$emit('input', $event.target.value)">
</template>
<script>
export default {
props: ['value']
};
</script>
<!-- Vue 3 自定义组件 -->
<template>
<input :modelValue="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>
<script>
export default {
props: ['modelValue']
};
</script>
4. 处理性能瓶颈
- 优化响应式数据:
- 避免不必要的响应式:
使用
ref
或reactive
时,确保只对需要响应式的部分进行定义。例如,如果一个对象只有部分属性需要响应式,可使用ref
包裹单个属性,而不是用reactive
包裹整个对象。 - 深度响应式与浅层响应式:
reactive
创建的是深度响应式对象,对于大型对象可能存在性能问题。如果不需要深度响应式,可使用shallowReactive
创建浅层响应式对象。例如:
- 避免不必要的响应式:
使用
import { shallowReactive } from 'vue';
const obj = shallowReactive({
data: {
subData: 'initial value'
}
});
// 直接修改 obj.data 不会触发视图更新,需手动处理
obj.data = { newSubData: 'new value' };
- 组件优化:
- 懒加载组件:
对于大型项目中不常用的组件,使用懒加载。在 Vue 3 中,可使用
defineAsyncComponent
实现。例如:
- 懒加载组件:
对于大型项目中不常用的组件,使用懒加载。在 Vue 3 中,可使用
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'));
- **缓存组件**:
对于频繁切换但内容不变的组件,可使用 keep - alive
进行缓存。在 Vue 3 中用法与 Vue 2 类似:
<keep - alive>
<component :is="currentComponent"></component>
</keep - alive>
5. 保证代码的可维护性和扩展性
- 代码结构优化:
- 文件夹和文件命名:
保持清晰的文件夹结构,按照功能或模块划分文件夹。文件命名采用有意义的命名方式,如
userInfo.js
、userList.vue
等。 - 逻辑分层:
将业务逻辑、数据获取、UI 展示等逻辑进行分层。例如,将数据获取逻辑放在
api
文件夹下的文件中,业务逻辑放在composables
文件夹下的自定义composable
函数中。
- 文件夹和文件命名:
保持清晰的文件夹结构,按照功能或模块划分文件夹。文件命名采用有意义的命名方式,如
- 文档编写:
- 组件文档:
为每个组件编写详细的文档,包括组件的功能、props、emits、使用示例等。可以使用
vue - docgen - api
等工具自动生成文档。 - 逻辑文档:
对于复杂的逻辑,特别是自定义
composable
函数,添加注释说明其功能、参数、返回值以及使用场景。
- 组件文档:
为每个组件编写详细的文档,包括组件的功能、props、emits、使用示例等。可以使用
- 测试与持续集成:
- 单元测试:
使用测试框架(如
jest
结合@vue/test - utils
)对组件和composable
函数进行单元测试。确保每个功能模块都有相应的测试用例覆盖。 - 集成测试:
进行集成测试,验证组件之间的交互和整个系统的功能。可以使用
cypress
等工具进行端到端测试。 - 持续集成:
设置持续集成(如使用
GitHub Actions
、GitLab CI
等),在每次代码提交或合并时自动运行测试,确保代码质量。
- 单元测试:
使用测试框架(如