Nuxt3+Supabase:点击按钮更新ref变量后无法重获数据求助
问题解决:点击按钮后数据不重新获取的原因及修复方案
核心问题分析
allOffers是异步函数,调用时需要用await等待结果,但原代码的点击事件里直接把Promise赋值给offers.value,导致视图无法正确渲染数据。- 此前尝试的watch未生效,大概率是监听写法不正确,或未正确触发数据更新逻辑。
修复步骤
1. 修复点击事件的异步处理
修改点击函数,添加await等待异步函数执行完成:
async function clickCountry(country) { country_id.value = country; offers.value = await allOffers(); } async function clickCategory(category) { category_id.value = category; offers.value = await allOffers(); }
2. 添加watch自动监听变量变化
通过watch同时监听country_id和category_id,当任意变量变化时自动重新获取数据:
import { watch } from 'vue'; // 在脚本末尾添加 watch([country_id, category_id], async () => { offers.value = await allOffers(); }, { immediate: true }); // immediate: true 确保组件初始化时自动执行一次,可替代初始的offers.value = await allOffers()
3. 优化allOffers函数(可选但推荐)
原函数存在大量重复代码,可合并查询逻辑减少冗余:
let allOffers = async () => { try { let query = supabase.from('offers').select('*'); // 处理国家过滤逻辑 if (country_id.value !== null) { query = query.or(`country_id.eq.${country_id.value},country_id.eq.1`); } // 处理分类过滤逻辑 if (category_id.value !== null) { query = query.eq(category_id.value.toLowerCase(), true); } const { data: offersData, error } = await query; if (error) throw error; // 去重(若or查询已保证数据唯一可省略此步骤) return offersData.reduce((accumulator, current) => { if (!accumulator.find(item => item.offer_id === current.offer_id)) { accumulator.push(current); } return accumulator; }, []); } catch (error) { console.error('获取数据失败:', error); return []; } }
完整修改后的脚本代码
import { ref, watch } from 'vue'; const supabase = useSupabaseClient(); let country_id = ref(null) let category_id = ref(null) let offers = ref([]) let allOffers = async () => { try { let query = supabase.from('offers').select('*'); if (country_id.value !== null) { query = query.or(`country_id.eq.${country_id.value},country_id.eq.1`); } if (category_id.value !== null) { query = query.eq(category_id.value.toLowerCase(), true); } const { data: offersData, error } = await query; if (error) throw error; return offersData.reduce((accumulator, current) => { if (!accumulator.find(item => item.offer_id === current.offer_id)) { accumulator.push(current); } return accumulator; }, []); } catch (error) { console.error('获取数据失败:', error); return []; } } // 监听变量变化自动更新数据 watch([country_id, category_id], async () => { offers.value = await allOffers(); }, { immediate: true }); async function clickCountry(country) { country_id.value = country; } async function clickCategory(category) { category_id.value = category; }
说明
- 点击事件现在只需修改响应式变量,watch会自动触发数据更新,无需在点击事件中重复调用
allOffers。 - 使用
or查询替代两次单独请求,减少Supabase调用次数,提升性能。 - 补充了错误日志输出,便于排查问题。
内容的提问来源于stack exchange,提问作者olivaxa
相关产品推荐
相关产品推荐

