Vue中user.displayName模板可访问但script内为undefined如何解决
问题原因
- ref对象未正确取值:你从composable拿到的
user是Vue的ref响应式对象,模板中Vue会自动解包ref,所以直接写user.displayName能正常渲染;但在JS代码中访问ref的真实值必须加上.value后缀,你直接写user.displayName本质是访问ref对象本身的displayName属性,自然是undefined。 - Firebase auth状态异步加载:
onAuthStateChanged是异步回调,组件onMounted触发时,这个回调大概率还没执行完成,初始的user.value是projectAuth.currentUser,用户未完成鉴权前这个值为null,就算加了.value也拿不到属性。
解决方法
第一步:修改组件逻辑
- 从Vue引入
watchAPI,监听user的变化,等user有有效值后再执行请求逻辑 - 所有JS代码中访问
user属性都加上.value,配合可选链?.避免空值报错 - 修复原代码中未定义的
error变量问题,以及Firebase查询结果的处理逻辑(get返回的是QuerySnapshot,不能直接filter,要走.docs属性)
修改后的组件代码:
<template> <p>Process Payroll</p> <h1>{{ user.displayName }} </h1> <h1>{{ docs }} </h1> </template> <script> import getUser from '@/composables/getUser' import { ref, watch } from 'vue' import { projectFirestore } from '@/firebase/config' export default { setup() { const { user } = getUser(); const lastName = ref(""); const firstName = ref(""); const docs = ref([]); const error = ref(null); const returnUser = async () => { // 先判断user有有效值再执行请求 if (!user.value?.displayName) return try { const res = await projectFirestore .collection("users") .where("displayName", "==", user.value.displayName) .get(); console.log(res); // QuerySnapshot要取docs属性再遍历 const matchedDocs = res.docs.filter(doc => { return doc.data().displayName === user.value.displayName }); docs.value = matchedDocs.map(doc => doc.data()); } catch (err) { error.value = err.message } }; // 监听user变化,有值就自动触发请求 watch(user, (newUser) => { if (newUser) returnUser() }, { immediate: true }) return { user, docs, returnUser }; }, } </script>
可选:优化getUser composable
可以加加载状态和错误状态,方便业务侧判断:
import { ref } from 'vue' import { projectAuth } from '../firebase/config' const user = ref(projectAuth.currentUser) const userLoading = ref(true) const userError = ref(null) projectAuth.onAuthStateChanged(_user => { console.log('User state change. Current user is:', _user) user.value = _user userLoading.value = false }, err => { userError.value = err userLoading.value = false }); const getUser = () => { return { user, userLoading, userError } } export default getUser
内容的提问来源于stack exchange,提问作者Bilal Hussain
相关产品推荐
相关产品推荐

