【问题标题】:Can't use vue-router and pinia inside a single store不能在单个商店内使用 vue-router 和 pinia
【发布时间】:2022-01-12 12:35:59
【问题描述】:

我正在使用 pinia 和 vue-router 4.x,但我在商店中使用它们时遇到了问题。 每个人都独立工作,但不能一起工作。

如果我使用

import router from '../router'

路由器可以工作,但 pinia 失败并出现错误

Uncaught ReferenceError: Cannot access 'useAuthStore' before initialization
at axiosroot.ts

@line let authStore = useAuthStore(pinia);

//这里是axiosroot.ts

import axios from "axios";
import {useAuthStore} from '../stores/auth-store'
import { createPinia } from "pinia";
 const pinia=createPinia();
let authStore = useAuthStore(pinia);
const url = "http://127.0.0.1:8000/api";
const   myToken =authStore.getToken;
export default axios.create({
  url,
  headers:{"Accept":"application/json"},
  
});

当我从 vue-router 导入路由器时,useRouter 未定义

import {useRouter} from 'vue-router'
const router =useRouter();

错误

Uncaught TypeError: Cannot read properties of undefined (reading 'push') 
--- 
error @ line router.push({name:'Login'})

//这里是剩下的相关代码


import { defineStore, acceptHMRUpdate } from "pinia";
//import router from '../router'
import {useRouter} from 'vue-router'
const router =useRouter();
export const useAuthStore = defineStore({
 id: "user",
 actions: {  
   LogOut(payload) {
     // this.DELETE_TOKEN(null);
     // this.UPDATE_LOGIN_STATUS(false);
     router.push({name:'Login'})
   },
 },
});

【问题讨论】:

    标签: vue.js vue-router pinia


    【解决方案1】:

    Router 必须用作 pinia 中的插件。我在 pinia.documentation https://pinia.vuejs.org/core-concepts/plugins.html

    中读到了这个

    当添加外部属性、来自其他库的类实例或简单的非反应性事物时,您应该在将对象传递给 pinia 之前使用 markRaw() 包装对象。这是将路由器添加到每个商店的示例:

    import { markRaw } from 'vue'
    // adapt this based on where your router is
    import { router } from './router'
    
    pinia.use(({ store }) => {
      store.router = markRaw(router)
    })
    

    这将为您创建的每个商店添加 pinia。 main.ts 中的配置与 vue 插件相同。

    import { createApp, markRaw } from 'vue';
    import { createPinia } from 'pinia';
    import App from './app/App.vue';
    import { router } from './modules/router/router';
    
    const app = createApp(App);
    const pinia = createPinia();
    
    pinia.use(({ store }) => {
      store.$router = markRaw(router)
    });
    app.use(router)
    

    现在您可以访问商店中的路由器了。

    export const useMyStore = defineStore("myStore", {
      state: () => {
        return {};
      },
      actions: {
        myAction() {
          this.$router.push({ name: 'Home' }); 
      },
    });
    
    

    【讨论】:

      【解决方案2】:

      我解决了将商店包装在一个函数中的问题:

      /*** THIS DOES NOT WORK ****/
      const router = useRouter();
      
      export const useLoginStore = defineStore("login", {
        state: () => ({
          loading: false,
          error: "",
        }),
        actions: {
          loginAction(credentials: AuthenticationRequest): Promise<void> {
            await login(credentials);
            router.replace("/")
          },
        },
      });
      
      
      
      /*** This actually works ***/
      export default function useLoginStore() {
        const router = useRouter();
      
        return defineStore("login", {
          state: () => ({
            loading: false,
            error: "",
          }),
          actions: {
            loginAction(credentials: AuthenticationRequest): Promise<void> {
              await login(credentials);
              router.replace("/")
            },
          },
        })();
      }
      

      【讨论】:

        【解决方案3】:

        如果您在 store 操作中而不是在模块顶部声明 const router = useRouter();,它应该可以工作。

        const store = useSomeStore() 声明也是如此。它们不能在模块路由中使用,并且经常在组件setup 函数和存储操作中使用。

        需要创建插件,但如果您可能在所有商店中使用路由器,则仍然值得这样做,如 this answer 中所述

        【讨论】:

          猜你喜欢
          • 2017-12-18
          • 2017-07-22
          • 2022-07-12
          • 1970-01-01
          • 2022-06-21
          • 2023-01-24
          • 2022-07-10
          • 2022-08-17
          • 1970-01-01
          相关资源
          最近更新 更多