面试题答案
一键面试模块划分
- 功能模块划分:根据业务功能将项目划分为独立的模块,例如用户模块、订单模块、商品模块等。每个模块包含自己的组件、逻辑和路由。
- 目录结构:
src/
├── modules/
│ ├── user/
│ │ ├── components/
│ │ │ ├── UserLogin.vue
│ │ │ ├── UserRegister.vue
│ │ ├── services/
│ │ │ ├── userApi.js
│ │ ├── stores/
│ │ │ ├── userStore.js
│ │ ├── userRoutes.js
│ │ ├── userModule.js
│ ├── order/
│ │ ├──...
├── App.vue
├── main.js
- 模块化导出:在每个模块的
userModule.js
中,使用export
导出模块相关的配置、函数等,便于在其他地方引用。
状态管理
- 使用 Vuex 结合 Composition API:
- 创建
store
文件夹,在每个模块的stores
目录下创建各自的状态管理文件,如userStore.js
。 - 在
userStore.js
中使用createStore
函数创建 Vuex 模块。
- 创建
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: null,
token: ''
}),
actions: {
async login(userData) {
// 调用登录接口
const response = await userApi.login(userData);
this.userInfo = response.data.user;
this.token = response.data.token;
}
}
});
- 在组件中使用:在组件中通过
useUserStore
函数获取状态和调用方法。
<template>
<button @click="login">登录</button>
</template>
<script setup>
import { useUserStore } from '@/modules/user/stores/userStore';
const userStore = useUserStore();
const login = () => {
userStore.login({ username: 'test', password: '123456' });
};
</script>
性能优化
- 代码分割:
- 使用
import()
动态导入组件。例如在路由配置中:
- 使用
const routes = [
{
path: '/user/login',
name: 'UserLogin',
component: () => import('@/modules/user/components/UserLogin.vue')
}
];
- 懒加载:
- 对于图片等资源,可以使用
loading="lazy"
属性实现浏览器原生的懒加载。 - 对于组件,除了上述路由的动态导入实现懒加载,还可以在父组件中使用
v-if
结合ref
和nextTick
实现条件懒加载。
- 对于图片等资源,可以使用
<template>
<div>
<button @click="loadComponent">加载组件</button>
<component v-if="isComponentLoaded" :is="loadedComponent"></component>
</div>
</template>
<script setup>
import { ref, nextTick } from 'vue';
const isComponentLoaded = ref(false);
const loadedComponent = ref(null);
const loadComponent = async () => {
await nextTick();
loadedComponent.value = await import('@/modules/user/components/UserInfo.vue');
isComponentLoaded.value = true;
};
</script>
解决代码耦合和可维护性问题
- 逻辑复用:通过
setup
函数将相关逻辑封装成可复用的函数。例如在多个组件中都需要获取用户信息,可以创建一个useUserInfo
函数。
import { ref, onMounted } from 'vue';
import { useUserStore } from '@/modules/user/stores/userStore';
export const useUserInfo = () => {
const userInfo = ref(null);
const userStore = useUserStore();
onMounted(() => {
userInfo.value = userStore.userInfo;
});
return { userInfo };
};
在组件中使用:
<template>
<div>
<p>{{ userInfo }}</p>
</div>
</template>
<script setup>
import { useUserInfo } from '@/modules/user/useUserInfo';
const { userInfo } = useUserInfo();
</script>
- 清晰的代码结构:
setup
函数内按照功能划分代码块,如数据定义、生命周期钩子、方法定义等,使代码结构清晰,易于维护。 - 依赖管理:在
setup
函数参数中明确声明依赖,通过解构获取依赖,提高代码的可理解性和可维护性。例如:
import { ref, computed, inject } from 'vue';
export default {
setup(props, { attrs, slots, emit }) {
const parentValue = inject('parentValue');
const localData = ref('');
const computedValue = computed(() => localData.value + parentValue);
const handleClick = () => {
emit('customEvent', computedValue.value);
};
return { localData, computedValue, handleClick };
}
};