代码之家  ›  专栏  ›  技术社区  ›  Brad

Vue Child组件对检索到的pinia/vueFire对象失去反应性

  •  0
  • Brad  · 技术社区  · 10 月前

    我正在尝试将项目加载到子组件中,以便编辑值。我正在通过一个 itemId 从父对象到子对象作为一个道具,在子对象中我调用一个函数 store.itemForId(id) 从vueFire/firstore集合中检索itemData。我可以在子项中检索项目文档,但它失去了反应性。如果firestore文档在外部更新,则pinia存储中的集合和父级中的数据会更新,但子级中检索到的项目不会。

    然而, 如果我在父级中使用相同的函数,而是将项目传递给子级,则反应性会保持不变。 这不是一个解决方案,因为我最终需要能够编辑该项目,但这让我觉得问题出在孩子身上。

    我有一家卖松果的商店 projectItems 收藏和a projectInfo 文件。

    projectInfo.itemOrder 给出项目的显示顺序。

    // projectStore.js
    const projectInfo = useDocument(() => doc(db, projectPath))
    const { data:projectItems, promise:itemsPromise } = useCollection(() => collection(db, itemsPath))
    
    
    function itemForId(id) {
      return projectItems.value.find((item) => item.id === id)
    }
    
    

    MyParent.vue

    <script setup>
      import { useProjectStore } from 'stores/projectStore'
    
      const projectStore = useProjectStore()
      const { projectInfo, projectItems } = storeToRefs(projectStore)
    </setup>
    <template>
    
      <div>Child gets Id</div> <!-- not reactive -->
      <template v-for="itemId in projectInfo.itemOrder" :key="itemId">
        <IdChild :itemId="itemId" /> 
      </template>
    
      <div>Child gets Item</div> <!-- reactive -->
      <template v-for="itemId in projectInfo.itemOrder" :key="itemId">
        <ItemChild :item="projectStore.itemForId(itemId)" /> 
      </template>
    
      <div>Raw ItemData</div> <!-- reactive -->
      <div>{{ projectItems }}</div> 
    </template>
    
    

    IdChild.vue没有反应

    <script setup>
      import { useProjectStore } from 'stores/projectStore'
      
      const props = defineProps({ itemId: String })
    
      const projectStore = useProjectStore()
      const { projectItems } = storeToRefs(projectStore)
    
      // this seems to be where reactivity is lost. Tried with both ref and without.
      // console.log(item) shows it as a RefImpl / Proxy so it seems correct
      const item = ref(projectStore.itemForId(props.itemId))
    
    
    </setup>
    <template>
    
      <div>{{ item.name }}</div> <!-- not reactive -->
      
      <!-- this is reactive but seems wrong to have to do for every value -->
      <div>{{ projectStore.itemForId(itemId).name }}</div> 
    
      <div>Raw ItemData</div> <!-- for troubleshooting... but reactive too -->
      <div>{{ projectItems }}</div> 
    </template>
    
    

    ItemChild.vue-为了排除故障,我也做了这个,它是反应性的,但由于该项目是作为道具传递的,因此不可编辑。

    <script setup>
      import { useProjectStore } from 'stores/projectStore'
      
      const props = defineProps({ item: Object })
    
    </setup>
    <template>
    
      <div>{{ item.name }}</div> <!-- reactive -->
      
    </template>
    
    

    我如何对 item 在我的孩子反应?

    或者,我对反应性的工作原理有什么不理解的地方吗?

    1 回复  |  直到 10 月前
        1
  •  0
  •   Estus Flask    10 月前

    反应性丧失,因为反应性对象在 setup 这可以有意地完成,以获取可变对象的初始状态。对于需要对计算对象的变化做出反应的只读对象,它应该是一个计算对象(因此得名):

    const item = computed(() => projectStore.itemForId(props.itemId));
    
    推荐文章