0

我正在使用 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'})
   },
 },
});
4

3 回答 3

1

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

/*** 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("/")
      },
    },
  })();
}
于 2022-01-27T07:53:26.573 回答
1

路由器必须用作 pinia 中的插件。我在 pinia.documentation https://pinia.vuejs.org/core-concepts/plugins.html中读到了这个

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

// 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() {
      router.push({ name: 'Home' }); 
  },
});

于 2022-01-29T12:07:13.207 回答
0

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

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

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

于 2022-02-28T09:34:24.360 回答