面试题答案
一键面试整体架构设计思路
- Vuex 模块划分:根据项目模块划分 Vuex 模块,每个模块负责管理自身相关的状态、mutations、actions。
- 异步逻辑封装:利用 Vue Composition API 的
setup
函数,将异步逻辑封装成可复用的函数,方便在组件和 Vuex actions 中调用。 - 数据依赖处理:通过 Promise 链式调用或
async/await
来处理数据之间的依赖关系。 - 重试机制:封装重试函数,在数据获取失败时调用。
关键代码片段
- Vuex 模块示例
// store/modules/user.js
import { defineStore } from 'pinia'
import { fetchUserData, fetchRelatedData } from '@/api/user'
import { retry } from '@/utils/retry'
export const useUserStore = defineStore('user', {
state: () => ({
userData: null,
relatedData: null,
isLoading: false
}),
actions: {
async fetchInitialData() {
this.isLoading = true
try {
// 先获取用户数据
const userRes = await retry(fetchUserData, 3)
this.userData = userRes.data
// 依赖用户数据获取相关数据
const relatedRes = await retry(() => fetchRelatedData(this.userData.id), 3)
this.relatedData = relatedRes.data
} catch (error) {
console.error('数据获取失败', error)
} finally {
this.isLoading = false
}
}
}
})
- 重试函数封装
// utils/retry.js
export function retry(fn, maxRetries = 3) {
return new Promise((resolve, reject) => {
const attempt = async (retries) => {
try {
const result = await fn()
resolve(result)
} catch (error) {
if (retries > 0) {
await new Promise(resolve => setTimeout(resolve, 1000))
await attempt(retries - 1)
} else {
reject(error)
}
}
}
attempt(maxRetries)
})
}
- 组件中调用
<template>
<div>
<button @click="fetchData">获取数据</button>
<div v-if="isLoading">加载中...</div>
<div v-if="userData">用户数据: {{ userData }}</div>
<div v-if="relatedData">相关数据: {{ relatedData }}</div>
</div>
</template>
<script setup>
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const isLoading = computed(() => userStore.isLoading)
const userData = computed(() => userStore.userData)
const relatedData = computed(() => userStore.relatedData)
const fetchData = async () => {
await userStore.fetchInitialData()
}
</script>
通过上述设计,将异步逻辑合理封装在 Vuex actions 中,并利用重试机制确保数据获取的可靠性,同时在组件中简洁地调用和展示数据,实现了高效、可维护的代码结构。