Vue3结合Firebase无法在template中访问ref对象属性
问题原因
你无法通过{{ lastEvent.startDate }}拿到数据有两个直接原因:
- 数据类型不匹配:你初始化
lastEvent时给的是空数组,查询到结果后也是把文档放进数组再赋值,最终lastEvent存的是长度为1的数组,不是单个事件对象。从你贴的控制台结构也能看到,_value字段是用[]包裹的数组,直接访问数组的startDate属性自然得到undefined。哪怕你用limit(1)限制只返回1条记录,Firebase的getDocs方法返回的始终是集合快照,不会直接返回单个文档对象。 - 判断条件失效:你写的
v-if="lastEvent"永远成立,因为空数组[]在JavaScript里是真值,页面会在数据还没异步加载完成时就尝试渲染,此时数组里还没有内容,自然拿不到值。
修复方法
1. 修改可组合函数getLastEvent-SO.js
既然只需要取最新1条记录,没必要用数组存储,直接存单个事件对象即可,同时补全错误捕获:
import { ref } from 'vue' import { db } from '@/firebase/config' import { collection, getDocs, query, where, orderBy, limit } from 'firebase/firestore' const getLastEvent = (u) => { // u = 用户id // 初始值设为null,方便模板判断数据是否加载完成 const lastEvent = ref(null) const error = ref(null) let collectionRef = collection(db, 'events') collectionRef = query( collectionRef, where("userId", "==", u ), orderBy("created", "desc"), limit(1) ) getDocs(collectionRef) .then(snapshot => { // 快照非空时直接取第一条文档,不需要循环 if (!snapshot.empty) { const doc = snapshot.docs[0] lastEvent.value = { ...doc.data(), id: doc.id } } }) .catch(err => { error.value = err.message console.log('获取最近事件失败:', err) }) return { lastEvent, error } } export default getLastEvent
2. 修改Vue组件代码
调整模板判断逻辑,数据加载完成后直接访问对象属性即可:
<template> <form @submit.prevent="handleSubmit"> <h2>新建事件</h2> <p v-if="lastEvent">上次开始日期: {{ lastEvent.startDate }}</p> <!-- 其余表单输入项 --> <button>添加事件</button> </form> </template> <script> import getUser from "@/composables/getUser"; import getLastEvent from "@/composables/getLastEvent-SO"; export default { setup() { const { user } = getUser(); const { lastEvent, error } = getLastEvent(user.value.uid) return { lastEvent, error }; }, }; </script>
表单预填充注意:不要直接把表单字段的
v-model绑定到lastEvent的属性上,否则用户修改表单时会直接改动查询得到的响应式值。正确做法是拿到lastEvent数据后,把需要的字段拷贝到专门存表单数据的响应式对象里作为初始值。
内容的提问来源于stack exchange,提问作者BGMX
相关产品推荐
相关产品推荐

