![](/img/trans.png)
[英]How can I create a reusable form component for each resource I create and/or update (Vue 3, vue-router, Pinia)
[英]Can't use vue-router and pinia inside a single store
我正在使用 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-routern 导入路由器时, 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'})
},
},
});
路由器必须用作 pinia 中的插件。 我在 pinia.documentation https://pinia.vuejs.org/core-concepts/plugins.html中读到了这个
添加外部属性时,来自其他库的 class 实例,或者只是非反应性的东西,您应该在将 object 传递给 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' });
},
});
我解决了将商店包装在 function 中的问题:
/*** 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("/")
},
},
})();
}
对于使用类星体 v2 的任何人。 这对我有用
在您的 /src/stores/index.js 文件中,添加以下内容
import { markRaw } from 'vue'
import { route } from 'quasar/wrappers'
pinia.use(({ store }) => {
// important! dont add a $router here
store.router = markRaw(router)
})
然后在您的 src/stores/[yourStore].js 文件中使用
this.router.push("/") // important! dont add a $router here
尝试按照最佳答案中的建议添加 $router 时遇到问题
如果您声明const router = useRouter();
它应该可以工作在您的商店操作中,而不是在模块的顶部。
const store = useSomeStore()
声明也是如此。 它们不能在模块路由中使用,并且通常在组件setup
功能和存储操作中使用。
您不需要创建插件,但如果您可能在所有商店中使用路由器,则仍然值得这样做,如本答案中所述
在main.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')
在您的商店推送路线:
this.router.push({ name: 'home' });
对于任何使用 quasar Framework v2 的人
找到 /src/stores/index.js 文件并编辑
import { useRouter } from 'vue-router' ---> import this
// You can add Pinia plugins here
// pinia.use(SomePiniaPlugin)
pinia.router = useRouter() ---> add this line
在存储文件中
this.router.push({ name: 'Home' }) --> use this
如果您像可组合的 function 一样编写您的 pinia 商店,那么在 pinia 商店中使用 vue-router 非常容易。 如果您已经熟悉组合 API,那么这些设置存储很容易编写。
import {
useRouter
} from "vue-router";
import {
ref,
computed
} from "vue"
import {
defineStore
} from "pinia";
export const useAuthStore = defineStore('authStore', () => {
const router = useRouter()
// your states are just reactive variables
const token = ref(localStorage.getItem('token'))
// your getters are just computed properties
const loginStatus = computed(() => {
return token.value ? true : false
})
// your actions are just javascript functions
const DELETE_TOKEN(payload) = () => {
token.value = payload
}
const UPDATE_LOGIN_STATUS = (payload) => {
loginStatus.value = payload;
}
const logOut(payload) {
DELETE_TOKEN(null);
UPDATE_LOGIN_STATUS(false);
router.push({
name: 'Login'
})
}
return {
token,
loginStatus,
DELETE_TOKEN,
UPDATE_LOGIN_STATUS,
logOut
}
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.