Estoy usando pinia y vue-router 4.x, pero tengo un problema al usar ambos en una tienda. cada uno trabaja independientemente, pero no juntos.
si uso
import router from '../router'el enrutador funcionará pero pinia falla con error
Uncaught ReferenceError: Cannot access 'useAuthStore' before initialization at axiosroot.ts @line let authStore = useAuthStore(pinia);//aquí está 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"}, }); Cuando importo un enrutador desde vue-routern useRouter no está definido
import {useRouter} from 'vue-router' const router =useRouter();el error
Uncaught TypeError: Cannot read properties of undefined (reading 'push') --- error @ line router.push({name:'Login'})// aquí está el código relevante restante
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'}) }, }, });El enrutador debe usarse como un complemento en pinia. Leí esto en pinia.documentation https://pinia.vuejs.org/core-concepts/plugins.html
Al agregar propiedades externas, instancias de clase que provienen de otras bibliotecas o simplemente cosas que no son reactivas, debe envolver el objeto con markRaw() antes de pasarlo a pinia. Aquí hay un ejemplo agregando el enrutador a cada tienda:
import { markRaw } from 'vue' // adapt this based on where your router is import { router } from './router' pinia.use(({ store }) => { store.router = markRaw(router) })Esto agregará pinia a cada tienda que cree. La configuración en main.ts es la misma que para los complementos de 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)Ahora puede acceder al enrutador en sus tiendas.
export const useMyStore = defineStore("myStore", { state: () => { return {}; }, actions: { myAction() { this.$router.push({ name: 'Home' }); }, });Resolví que envolver la tienda en una función:
/*** 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("/") }, }, })(); }En principal.js :
import { createApp, markRaw } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' const pinia = createPinia() pinia.use(({ store }) => { store.router = markRaw(router) }) const app = createApp(App) app.use(pinia) app.use(router) app.mount('#app')En tu tienda empuja rutas con:
this.router.push({ name: 'home' });