如何在Vue中向Pinia Getter传递参数?附代码示例
问题:Pinia带参数Getter无法正确传递ID获取对应Thread
我想在组件的computed中映射Pinia store里的thread getter,并在模板中使用,但无法正确传递ID参数来获取对应的thread。原本教程用Vuex,现在转Pinia过程中遇到了困惑。
ThreadsStore 代码
import { defineStore } from "pinia"; import sourceData from "@/data.json"; import { useUsersStore } from "../stores/UsersStore"; import { usePostsStore } from "../stores/PostsStore"; import { useForumsStore } from "../stores/ForumsStore"; import { findById, upsert } from "@/helpers"; export const useThreadsStore = defineStore("ThreadsStore", { state: () => { return { threads: sourceData.threads, }; }, getters: { thread: (state) => { return (id) => { const thread = findById(state.threads, id); return { ...thread, get author() { return findById(useUsersStore().users, thread.userId); }, get repliesCount() { return thread.posts.length - 1; }, get contributorsCount() { return thread.contributors.length; }, }; }; }, }, actions: { async createThread({ text, title, forumId }) { const id = "ggqq" + Math.random(); const userId = useUsersStore().authId; const publishedAt = Math.floor(Date.now() / 1000); const thread = { forumId, title, publishedAt, userId, id }; this.threads.push(thread); this.appendThreadToUser({ userId, threadId: id }); this.appendThreadToForum({ forumId, threadId: id }); usePostsStore().createPost({ text, threadId: id }); return findById(this.threads, id); }, async updateThread({ title, text, id }) { const thread = findById(this.threads, id); const post = findById(usePostsStore().posts, thread.posts[0]); const newThread = { ...thread, title }; const newPost = { ...post, text }; this.setThread({ thread: newThread }); this.setPost({ post: newPost }); return newThread; }, appendThreadToForum({ forumId, threadId }) { const forum = findById(useForumsStore().forums, forumId); forum.threads = forum.threads || []; forum.threads.push(threadId); }, appendThreadToUser({ userId, threadId }) { const user = findById(useUsersStore().users, userId); user.threads = user.threads || []; user.threads.push(threadId); }, setPost({ post }) { upsert(usePostsStore().posts, post); }, setThread({ thread }) { upsert(this.threads, thread); }, }, });
页面组件代码
<template> <div class="col-large push-top"> <h1> {{ thread.title }} <router-link :to="{ name: 'ThreadEdit', id: this.id }" class="btn-green btn-small" > Edit Thread </router-link> </h1> <p> By <a href="#" class="link-unstyled">{{ thread.author.name }}</a >, <AppDate :timestamp="thread.publishedAt" />. <span style="float: right; margin-top: 2px" class="hide-mobile text-faded text-small" >{{ thread.repliesCount }} replies by {{ thread.contributorsCount }} contributors</span > </p> <post-list :posts="threadPosts" /> <post-editor @save="addPost" /> </div> </template> <script> import { mapState, mapActions } from "pinia"; import { useThreadsStore } from "../stores/ThreadsStore"; import { usePostsStore } from "../stores/PostsStore"; import PostList from "@/components/PostList"; import PostEditor from "@/components/PostEditor"; export default { name: "ThreadShow", components: { PostList, PostEditor, }, props: { id: { required: true, type: String, }, }, computed: { ...mapState(useThreadsStore, ["threads", "thread"]), ...mapState(usePostsStore, ["posts"]), threadPosts() { return this.posts.filter((post) => post.threadId === this.id); }, }, methods: { ...mapActions(usePostsStore, ["createPost"]), addPost(eventData) { const post = { ...eventData.post, threadId: this.id, }; this.createPost(post); }, }, }; </script>
解决方案
问题出在Pinia的带参数Getter不能直接通过mapState映射后在模板中直接访问属性。mapState会把thread getter作为一个函数映射到组件中,模板里的{{ thread.title }}实际上是在访问这个函数的title属性,自然取不到正确值。
修改组件的computed部分,手动定义thread计算属性,调用store的thread getter并传入当前组件的id参数:
<script> import { mapState, mapActions } from "pinia"; import { useThreadsStore } from "../stores/ThreadsStore"; import { usePostsStore } from "../stores/PostsStore"; import PostList from "@/components/PostList"; import PostEditor from "@/components/PostEditor"; export default { name: "ThreadShow", components: { PostList, PostEditor, }, props: { id: { required: true, type: String, }, }, computed: { ...mapState(useThreadsStore, ["threads"]), // 移除对`thread`的映射 ...mapState(usePostsStore, ["posts"]), thread() { // 手动调用store的thread getter并传入id const threadsStore = useThreadsStore(); return threadsStore.thread(this.id); }, threadPosts() { return this.posts.filter((post) => post.threadId === this.id); }, }, methods: { ...mapActions(usePostsStore, ["createPost"]), addPost(eventData) { const post = { ...eventData.post, threadId: this.id, }; this.createPost(post); }, }, }; </script>
也可以选择不使用mapState,直接在computed中获取store实例:
computed: { threadsStore() { return useThreadsStore(); }, postsStore() { return usePostsStore(); }, thread() { return this.threadsStore.thread(this.id); }, threadPosts() { return this.postsStore.posts.filter((post) => post.threadId === this.id); }, },
这样就能正确获取到对应ID的thread,并在模板中访问它的属性了。
内容的提问来源于stack exchange,提问作者Corey Bryant
相关产品推荐
相关产品推荐

