我正在使用 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)
}
}
)
我在正在从事的项目中遇到过类似的情况。首先,我通过使用 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() 方法,并让脚本在进一步执行之前等待它,确保变量及时收到分配的值
希望这个经验对你有帮助