我正在使用Vue,Pinia和Router做一个小练习,我面临着从一个简单的json服务器中检索数据的问题,我将尽可能简短地解释自己:
假设我的商店配置(简化)是:
import { defineStore } from 'pinia'
import {fetchTasks} from '../utils/utils.js'
const SERVER_URL = "http://localhost:3001";
export const useTaskStore = defineStore('taskStore', {
state: () => ({
tasks: [],
singletask: []
}),
getters: {
},
},
actions: {
async getTasks() {
this.tasks = await fetchTasks(`${SERVER_URL}/tasks`)
},
async getSingleTask(id) {
this.singletask = await fetchTasks(`${SERVER_URL}/tasks/${id}`);
}
}
})
utils中的fetchTask函数很简单:
const fetchTasks = async (url) => {
try {
const res = await fetch(url);
const data = await res.json();
return data;
} catch (e) {
console.error(e);
}
};
例如,响应http://localhost:3001/tasks类似于:
[
{
"id": 1,
"title": "First Task"
},
{
"id": 2,
"title": "Second Task"
},
{
"id": 3,
"title": "Third Task"
}
]
而对于例如http://localhost:3001/tasks/1类似于:
{
"id": 1,
"title": "First Task"
}
任务列表的组成部分是:
<script setup>
import TaskItemComponent from './TaskItem.vue'
import { useTaskStore } from '@/stores/taskStore'
import { storeToRefs } from 'pinia'
const taskStore = useTaskStore();
const {tasks} = storeToRefs(taskStore);
</script>
<template>
<div class="max-w-5xl mx-auto">
<template>
<TaskItemComponent v-for="t, index in tasks"
:key = "index"
:task = "t"
/>
</template>
</div>
</template>
和TaskItemComponent组件:
<script setup>
import { useTaskStore } from '@/stores/taskStore'
import { useRouter } from 'vue-router'
const props = defineProps(
{task: {type: Object} }
)
const taskStore = useTaskStore();
const router = useRouter();
const handleClick = () => {
router.push({name:'taskdetail',params:{'id':props.task.id}})
}
</script>
<template>
<div class="flex flex-row gap-2 bg-green-100 hover:bg-green-300 m-4 p-4 rounded-md cursor-pointer" @click="handleClick">
<h3>{{ task.title}}</h3>
<p class="text-xs">(id:{{ task.id }})</p>
</div>
</template>
到目前为止一切正常。
当我点击一个“task item”来启动“taskdetail”路由时,问题就出现了--我想填充使用函数getSingleTask获取的数据
到目前为止,我写的组件的任务细节
<script setup>
import {onMounted,toRefs} from 'vue';
import { useTaskStore } from '@/stores/taskStore';
import { useRouter } from 'vue-router';
import { storeToRefs } from 'pinia'
const taskStore = useTaskStore();
const {singletask} = storeToRefs(taskStore)
const router = useRouter();
const props = defineProps(['id'])
const {id} = toRefs(props);
const getTask = (id) => {
taskStore.getSingleTask(id);
console.log(taskStore.singletask.id)
if (!taskStore.singletask.id) {
router.replace({name:'notfound'})
}
}
onMounted(()=>{
getTask(id.value);
})
</script>
<template>
<div class="max-w-5xl mx-auto p-8">
<template v-if="singletask.id">
<div class="mt-4 p-4 bg-red-300 text-xl font-bold rounded-t-xl">
ID:{{singletask.id}}
</div>
<div class="flex p-4 bg-green-200 h-96 items-center text-center align-middle rounded-b-xl">
{{singletask.title}}
</div>
</template>
</div>
</template>
问题出在哪里?我第一次点击一个任务时,应用程序转到404,因为' www.example.com '的值taskStore.singletask.id未定义(从console.log检查)我已经明白,每次点击时,id的值都是前一次点击的。
我不知道我做错了什么
谢谢你的帮助,告诉我如果你需要更多的信息。
1条答案
按热度按时间atmip9wb1#
在
taskdetail
路由中,getSingleTask
被调用,在它完成之前,你试图访问单个任务。尝试在
taskStore.getSingleTask(id)
之前添加await
,并将getTask
设置为一个cnrc函数。(或使用then .. catch
)您可以在
singletask
状态下给予加载消息。