vue.js 如何从另一个行动调用Pinia行动?

omhiaaxx  于 2023-05-18  发布在  Vue.js
关注(0)|答案(4)|浏览(358)

有没有一种方法可以从同一商店的另一个动作调用Pinia商店动作?例如,我有Pinia商店这样:

export const useCounter = defineStore({
    id: 'counter',

    state: () => ({
        counter: 0
    }),

    actions: {
        addOne() {
            this.state.counter++
        },
        addTwo() {
            // Can i call here addOne action?
            // Things like this not working:
            this.addOne();
            this.addOne();
            // This is not working too:
            this.actions.addOne();
            this.actions.addOne();
        }
    }
});

我可以在addTwo中调用addOne操作吗?

cunj1qz1

cunj1qz11#

您确实可以通过this访问同一存储的方法。只是用在自己店里的动作方法上。getPost操作方法通过thischeckPostfetchPost)访问同一存储中的多个方法,它工作得很好。

import {defineStore} from 'pinia';
import axios from 'axios';
const axiosInstance = axios.create({
    baseURL: window.wue.restUrl,
})

export const useBlogStore = defineStore(
    'blog',
    {
        state: () => ({
            posts: [],

        }),
        getters: {
            postCount(state) {
                return state.posts.length;
            },
            checkPost(state) {
                return (property, value) => (state.posts.find(post => post[property] === value));
            }
        },
        actions:{
            addPost(post) {
                this.posts.push(post)
            },
            async getPost(property, value) {
                if (this.checkPost(property, value)) {
                    return this.checkPost(property, value);
                } else {
                    return this.fetchPost(property, value);
                }
            },
            async fetchPost(property, value) {
                try {
                    let json;
                    if (property === "slug") {
                        json = await axiosInstance.get(`posts?slug=${value}`);
                    } else if (property === "id") {
                        json = await axiosInstance.get(`posts/${value}`);
                    }
                    const post = json.data[0];
                    this.addPost(post);
                    return post;
                } catch (error) {
                    alert(error);
                    console.log(error);
                }
            },
     }
});
zzwlnbp8

zzwlnbp82#

经过一番研究,我找到了某种答案。不相信这样做是可以的,但这是有效的。
基本上,我们只需要调用主存储函数(在我的例子中,这是useCounter)就在action内部,我们需要调用来自相同存储的另一个action,然后像往常一样调用存储的action。

export const useCounter = defineStore({
    id: 'counter',

    state: () => ({
        counter: 0
    }),

    actions: {
        addOne() {
            this.state.counter++
        },
        addTwo() {
            const counterStorage = useCounter();
            counterStorage.addOne();
            counterStorage.addOne();
        }
    }
});

在Pinia文档中有一个这样的例子,但它说我们可以这样做来调用来自另一个存储的操作,所以这让我困惑。

rbl8hiat

rbl8hiat3#

场景1 -使用Vue 3 + Pinia(optionsAPI)+ Fetch(而不是AXIOS)。

a.在同一个商店中,我可以通过使用“this.action_b”从一个action(例如action_a)调用另一个action(例如action_b)。(这是FullStack Alex在上面提到的回应)。
B.然而,当我尝试调用action_b作为action_a中的FETCH响应的一部分时,这不起作用。在这种情况下,由Назар Семен к提供的回应起了作用。也就是说,在action_a中,我不得不再次调用store作为变量(例如store_x),然后使用它作为前缀调用action_b(store_x.action_b)。
所用FETCH代码按照https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch中提供的格式

export const useixStore = defineStore('ix', {
state: () => ({...}),
actions: {
  action_b () {...},
  action_a () {
    ...
    const ix = useixStore(); // INTRODUCED TO MAKE THIS WORK
    ...
      async function postData(url = "", data = {}) {
    // Default options are marked with *
    const response = await fetch(url, {
      method: "POST", // *GET, POST, PUT, DELETE, etc.
      mode: "cors", // no-cors, *cors, same-origin
      cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
      credentials: "same-origin", // include, *same-origin, omit
      headers: {
        "Content-Type": "application/json",
        // "Content-Type": "application/json;charset=UTF-8",
      },
      redirect: "follow", // manual, *follow, error
      referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
      body: JSON.stringify(data), // body data type must match "Content-Type" header
    });
    return response.json(); // parses JSON response into native JavaScript objects
  }
  postData(url, i_json)
  .then(function(res) {
    ... 
    this.action_b   // THIS DOES NOT WORK
    ix.action_b     // THIS WORKED AFTER INTRODUCING ix WITHIN THIS action_a
    ...
  });
....

场景2 -使用Vue 3 + Pinia(setup)+ Fetch(而不是AXIOS)。

在这个使用Pinia的场景中(* 使用setup而不是OptionsAPI*),一切正常。
a.在同一个商店中,我可以通过使用“action_b”从一个动作(例如action_a)调用另一个动作(例如action_b)。(这类似于上面FullStack Alex提到的响应)。B.即使在FETCH响应中,这也会像预期的那样工作,并且简单的“action_b”工作。

hvvq6cgz

hvvq6cgz4#

顶部响应(FullStack Alex)在Typescript中不起作用。我终于发现了这个问题:https://github.com/vuejs/pinia/discussions/1299
从本质上看,你的getter需要通过键入。一旦我这样做了,我就能够在行动中使用我的吸气剂。

相关问题