vue3 pinia问题?

pinia

import {defineStore} from 'pinia'

export const useMy = defineStore('my', () => {
    return {user_id:'',username:''}
})

router

import { useMy } from '@/stores/my'


router.beforeEach(async (to, from, next) => {

    const my = useMy();
    my.user_id = 1;
    my.username = 'user';

    next();
})

HomeView.vue

<template>
    <H1>HomeView.vue</H1>
</template>

<script>
import {useMy} from "@/stores/my";

export default {
    name: "HomeView",
    setup() {

        const my = useMy();

        console.log(my.username)

        return {my}
    }
}

我在router.beforeEach中设置了,为什么组件中HomeView.vue里面的console.log(my.username)为空

阅读 2.1k
3 个回答
✓ 已被采纳

问题出在你在组件中使用 useMy() ,它创建了一个新的 store 实例而不是你在 router.beforeEach 中设置的那个实例。

为了在不同的组件中共享相同的 store 实例,你需要在组件中使用 useStore() 方法,并将它传递给组件:

vue
Copy code

<template>
  <h1>HomeView.vue</h1>
</template>

<script>
import { useStore } from 'pinia'

export default {
  name: 'HomeView',
  setup() {
    const store = useStore()
    console.log(store.my.username)

    return { store }
  }
}
</script>

在 useStore() 方法中不需要传递参数,因为它默认使用主 store。

另外,在你的路由守卫中也有一个问题,你需要在 useMy() 方法中传递一个唯一的 ID,以确保它返回正确的 store 实例:

router.beforeEach(async (to, from, next) => {
  const my = useMy('my-store') // 传递一个唯一的 ID
  my.user_id = 1
  my.username = 'user'
  next()
})

这将确保你在路由守卫中设置的是同一个 store 实例,可以在组件中共享和访问该实例。

无论是vuex还是pinia,都不太建议直接在state上去修改或者变动数据,像vuex是可以在 actionsmutations 下,那么 pinia 则是只有一个 actions, 来针对state的数据修改。

// Example File Path:
// ./src/stores/counter.js

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++
    }
  }
})

还有一个就是你通过 store.$patch 的方式去修改state也是可以的。mutating-the-state

store.$patch({
  count: store.count + 1,
  age: 120,
  name: 'DIO',
})

以上都是官网的案例,你针对你的进行修改就好,最方便的就是把你的beforeEach那部分改为:

router.beforeEach(async (to, from, next) => {

    const my = useMy();
    my.$patch({
        "user_id": 1,
        "username": "user",
    })
    // my.user_id = 1;
    // my.username = 'user';

    next();
})

要用 action。你可以先了解下 pinia 等状态管理工具的设计动机和原理。

store.js

const useStore = defineStore('store', () => {
  const username = ref('');
  function setUserName(value) {
    username.value = value;
  }
  return {
    username,
    setUserName,
  };
});

router

router.beforeEach(async (to, from, next) => {
    const store = useStore();
    store.setUserName('muimui');
    next();
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题