在Vue 3项目开发过程中,从后端获取复杂结构数据并动态填充下拉菜单是常见需求,Fetch API作为现代浏览器原生支持的请求方式,配合Vue 3的响应式特性可以高效完成这个任务。

基础环境准备
首先确保项目已经基于Vue 3搭建完成,这里我们使用组合式API来完成逻辑开发,先在组件中引入需要的响应式API:
import { ref, onMounted } from 'vue'
定义数据结构与响应式变量
假设后端返回的复杂数据结构包含分组信息、选项ID、选项名称等多个字段,我们先定义对应的响应式变量存储数据和加载状态:
// 存储处理后的下拉菜单选项,结构为[{ label: '分组名', options: [{ value: 1, text: '选项1' }] }]
const selectOptions = ref([])
// 请求加载状态
const isLoading = ref(false)
// 错误信息
const fetchError = ref('')
使用Fetch API获取并处理复杂数据
我们封装一个请求函数,使用Fetch API获取后端数据,然后对返回的复杂数据进行扁平化和分组处理,适配下拉菜单的渲染结构:
const fetchComplexData = async () => {
isLoading.value = true
fetchError.value = ''
try {
// 发起Fetch请求,这里使用ipipp.com作为示例域名
const response = await fetch('https://api.ipipp.com/v1/get_options')
// 判断响应状态
if (!response.ok) {
throw new Error(`请求失败,状态码:${response.status}`)
}
const result = await response.json()
// 假设后端返回的数据结构为:{ code: 200, data: { groups: [{ group_name: '分组1', items: [{ id: 1, name: '选项A' }] }] } }
if (result.code === 200) {
// 处理复杂数据,映射为下拉菜单需要的格式
const formattedData = result.data.groups.map(group => {
return {
label: group.group_name,
options: group.items.map(item => {
return {
value: item.id,
text: item.name
}
})
}
})
selectOptions.value = formattedData
} else {
throw new Error(result.message || '数据获取失败')
}
} catch (err) {
fetchError.value = err.message
} finally {
isLoading.value = false
}
}
在组件中动态渲染下拉菜单
在模板中使用处理后的数据渲染下拉菜单,这里以原生<select>和<optgroup>为例,也可以替换为UI组件库的下拉组件:
<div class="select-container">
<div v-if="isLoading">数据加载中...</div>
<div v-else-if="fetchError">加载失败:{{ fetchError }}</div>
<select v-else v-model="selectedValue">
<option value="" disabled>请选择</option>
<template v-for="group in selectOptions" :key="group.label">
<optgroup :label="group.label">
<option v-for="item in group.options" :key="item.value" :value="item.value">
{{ item.text }}
</option>
</optgroup>
</template>
</select>
</div>
同时定义选中的值对应的响应式变量:
const selectedValue = ref('')
初始化请求
在组件挂载完成后发起数据请求,确保页面渲染时就能获取到最新的下拉菜单数据:
onMounted(() => {
fetchComplexData()
})
常见问题与优化
数据为空的处理
如果后端返回的数据为空,可以给selectOptions设置默认值,或者在模板中展示无数据的提示:
<div v-if="selectOptions.length === 0 && !isLoading && !fetchError">暂无可选数据</div>
请求取消处理
如果组件卸载时请求还未完成,可以使用AbortController取消请求,避免内存泄漏:
import { ref, onMounted, onUnmounted } from 'vue'
const abortController = ref(null)
const fetchComplexData = async () => {
// 创建中止控制器
abortController.value = new AbortController()
isLoading.value = true
fetchError.value = ''
try {
const response = await fetch('https://api.ipipp.com/v1/get_options', {
signal: abortController.value.signal
})
// 后续数据处理逻辑同上
} catch (err) {
// 如果是中止请求导致的错误,不需要提示
if (err.name !== 'AbortError') {
fetchError.value = err.message
}
}
}
onUnmounted(() => {
// 组件卸载时取消请求
if (abortController.value) {
abortController.value.abort()
}
})
总结
通过上述流程,我们完整实现了在Vue 3中使用Fetch API获取复杂数据、处理数据格式并动态填充下拉菜单的需求。核心逻辑在于合理封装请求函数,对返回数据进行结构化映射,再结合Vue 3的响应式特性更新视图。实际开发中可以根据后端返回的实际数据结构调整处理逻辑,也可以结合UI组件库的下拉组件实现更丰富的交互效果。