vue.js pinia存储从获取的数据似乎没有React

wh6knrhe  于 2023-10-23  发布在  Vue.js
关注(0)|答案(1)|浏览(178)

我正在使用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的值都是前一次点击的。
我不知道我做错了什么
谢谢你的帮助,告诉我如果你需要更多的信息。

atmip9wb

atmip9wb1#

taskdetail路由中,getSingleTask被调用,在它完成之前,你试图访问单个任务。
尝试在taskStore.getSingleTask(id)之前添加await,并将getTask设置为一个cnrc函数。(或使用then .. catch
您可以在singletask状态下给予加载消息。

相关问题