如何在Vue3组件中等待Pinia存储数据初始化后再分配变量?

问题描述 投票:0回答:1

我正在使用 Pinia 构建一个 Vue.js 应用程序进行状态管理。在我的组件中,我需要根据从 Pinia 商店检索的数据分配变量。但是,我遇到了一个问题,即组件在初始化存储数据之前分配变量,从而导致未定义的错误。使用浏览器扩展,我可以查看我的商店,其中填充了从 json 文件中提取的 5 个对象。在控制台中我得到:task.value 未定义。 我尝试了 ChatGPT 的一些建议,例如使用 watch 或 watchEffect,但到目前为止没有任何效果。

这是我的设置的简化版本:

// Pinia storesetup
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useTaskStore = defineStore('tasks', () => {
  const tasks = ref([])

  async function fetchData() {
    try {
      const response = await fetch('/src/data.json')
      if (!response.ok) {
        throw new Error('Failed to fetch data')
      }
      const data = await response.json()
      tasks.value = data.tasks
    } catch (error) {
      console.error('Error fetching tasks:', error)
    }
  }

  const getTaskById = computed(() => {
    return (taskId) => tasks.value.find((task) => task.id === taskId)
  })

  function addTask(task) {
    tasks.value.push(task)
  }

  function deleteTask(task) {
    const index = tasks.value.findIndex((t) => t.id === task.id)
    if (index !== -1) {
      tasks.value.splice(index, 1)
    }
  }

  fetchData()

  return {
    addTask,
    deleteTask,
    getTaskById,
    tasks
  }
})

这是我的组件(简化为模板并不重要):

<script setup>
import { ref, onMounted, watchEffect, computed } from 'vue'
import { useTaskStore } from '@/stores/TaskStore'
const props = defineProps({
  id: {
    type: String,
    required: true
  }
})
const store = useTaskStore()

const task = computed(() => store.getTaskById(props.id))

let titleEditing = ref(false)
let descriptionEditing = ref(false)
const editedTitle = ref(task.value.title)

我尝试过使用 onMounted、beforeMounted、watchEffect 和 watch。我尝试声明一个带有空对象引用的 const,并使用 watchEffect/watch 在状态更改时更新对象。

我期望 beforeMounted 能够工作,因为在安装组件之前,存储将被初始化并填充数据,并且变量将填充来自存储的数据,但事实并非如此。

尝试使用手表:

watch(
  () => store.tasks,
  (newTasks, oldTasks) => {
    if (newTasks !== oldTasks) {
      task.value = store.getTaskById(props.id)
    }
  }
)
vue.js asynchronous vuejs3 state-management pinia
1个回答
0
投票

我在正在从事的项目中遇到过类似的情况。首先,我通过使用 watch() 检查它是否是第一次加载,以及 watchEffect() 来解决它是否已经加载并且内部发生了一些变化。

过了一段时间,我找到了一种更好的方法,这是显而易见的

问题是:“变量无法接收值,因为承诺没有及时解决” 解决方案:“让程序等待”

这是我的pinia fetchData 代码:

async fetchData() {
  if (!this.dataLoaded && this.agentsTable.length == 0) {
    try {
      const response = await axios.get(`/api/agents`);
      response.data.forEach(agent => {
        this.agentsTable.push(agent);
      });
      this.dataLoaded = true;
    } catch (error) {
      console.error('Error in request api agents', error);
      if (error.response && error.response.status === 401 || error.code == 'ERR_NETWORK' || error.code =='ERR_CONNECTION_REFUSED') {
        this.logout();
      }
    }
  }
},

这是我在模板脚本中管理它的方法:

import { useCachedDataStoreAgents } from '../../stores/agentsStore';
 async function fetchData() {
       await useCachedDataStoreAgents().fetchData();
       loadingFlag.value = false;
 }
 fetchData();

在 pinia 存储的导入元素上调用 fetchData() 方法,并让脚本在进一步执行之前等待它,确保变量及时收到分配的值

希望这个经验对你有帮助

© www.soinside.com 2019 - 2024. All rights reserved.