面试题答案
一键面试1. 代码结构组织
- 目录结构:采用清晰的分层结构,例如:
src/ ├── api/ # 存放API请求相关代码 │ ├── userApi.ts │ └── productApi.ts ├── components/ # 组件目录 │ ├── atoms/ # 原子组件 │ │ ├── Button.vue │ │ └── Input.vue │ ├── molecules/ # 分子组件 │ │ ├── Form.vue │ │ └── Card.vue │ └── organisms/ # 有机体组件 │ ├── Header.vue │ └── Footer.vue ├── composables/ # 可复用的组合式函数 │ ├── useFetch.ts │ └── useLocalStorage.ts ├── stores/ # 状态管理 │ ├── userStore.ts │ └── appStore.ts ├── types/ # 自定义类型定义 │ ├── userTypes.ts │ └── productTypes.ts ├── views/ # 页面视图 │ ├── Home.vue │ └── About.vue ├── App.vue └── main.ts
- 文件命名规范:使用有意义的命名,如
userService.ts
表示用户相关服务,productModel.ts
表示产品相关的数据模型。
2. 模块划分
- 功能模块:按照业务功能划分模块,例如用户模块、产品模块等。每个模块有自己独立的
api
、components
、types
等子目录。以用户模块为例:src/ ├── user/ │ ├── api/ │ │ └── userApi.ts │ ├── components/ │ │ ├── UserLogin.vue │ │ └── UserProfile.vue │ ├── composables/ │ │ └── useUser.ts │ ├── stores/ │ │ └── userStore.ts │ ├── types/ │ │ └── userTypes.ts │ └── views/ │ └── UserDashboard.vue
- 通用模块:将一些通用的功能提取到单独模块,如
composables
中的通用组合式函数,utils
中的工具函数等。
3. 处理类型依赖
- 类型导出与导入:在
types
目录下定义类型,然后在需要的地方导入。例如在userTypes.ts
中定义用户类型:// userTypes.ts export interface User { id: number; name: string; email: string; }
// userApi.ts import { User } from '../types/userTypes'; import axios from 'axios'; export const getUser = async (id: number): Promise<User> => { const response = await axios.get(`/api/users/${id}`); return response.data; };
- 泛型使用:在函数和组件中使用泛型来提高类型灵活性。例如定义一个通用的
fetch
函数:// useFetch.ts import axios from 'axios'; const useFetch = <T>(url: string) => { const fetchData = async (): Promise<T> => { const response = await axios.get(url); return response.data; }; return { fetchData }; }; export default useFetch;
// productApi.ts import useFetch from '../composables/useFetch'; import { Product } from '../types/productTypes'; const { fetchData } = useFetch<Product[]>('/api/products');
4. 共享状态处理
- Vuex或Pinia:使用状态管理库,如Pinia。以Pinia为例,创建一个
userStore.ts
:
在组件中使用:// userStore.ts import { defineStore } from 'pinia'; import { User } from '../types/userTypes'; export const useUserStore = defineStore('user', { state: () => ({ currentUser: null as User | null }), actions: { setUser(user: User) { this.currentUser = user; } } });
<template> <div> <button @click="setUser({ id: 1, name: 'John', email: 'john@example.com' })">Set User</button> <p v-if="currentUser">{{ currentUser.name }}</p> </div> </template> <script setup lang="ts"> import { useUserStore } from '../stores/userStore'; const userStore = useUserStore(); const { currentUser, setUser } = userStore; </script>
- Provide / Inject:对于一些组件树内的共享状态,可以使用
provide
和inject
。例如在父组件中:
在子组件中:<template> <div> <ChildComponent /> </div> </template> <script setup lang="ts"> import { provide } from 'vue'; import ChildComponent from './ChildComponent.vue'; const sharedValue = 'Hello from parent'; provide('sharedValue', sharedValue); </script>
<template> <div> <p>{{ injectedValue }}</p> </div> </template> <script setup lang="ts"> import { inject } from 'vue'; const injectedValue = inject('sharedValue'); </script>