Reputation: 20733
I'm implementing a auth store(with firebase) and depending on the auth I want to route my user to login/logged page.
I'm basically trying to accomplish this: https://github.com/dannyconnell/vue-composition-api-course/blob/module-23/vue-composition-api-noteballs/src/stores/storeAuth.js
but in typescript.
In my main.ts
, I did declare the store as property:
const app = createApp(App);
const pinia = createPinia();
pinia.use(({ store }) => {
store.router = markRaw(router);
});
app.use(pinia);
app.use(router);
app.mount('#app');
But still, in my store, it doesn't know that I've a router property:
export const useStoreAuth = defineStore('storeAuth', {
state: () => {
return {
user: {},
} as AuthState;
},
actions: {
init() {
onAuthStateChanged(auth, user => {
if (user && user.uid && user.email) {
this.user = { id: user.uid, email: user.email };
this.router.push('/'); //--> router doesn't exists
} else {
this.user = null;
this.router.replace('/auth');//--> router doesn't exists
}
});
},
//...
}
});
this.router doesn't exist, I get the following error:
Property 'router' does not exist on type '{ init(): void; registerUser(credentials: any): void; loginUser(credentials: any): void; logoutUser(): void; } & { user: { id: string; email: string; } | null; } & _StoreWithState<"storeAuth", AuthState, {}, { ...; }> & _StoreWithGetters<...> & PiniaCustomProperties<...>'.ts(2339)
So how can I make my store aware that the router
property exists on the created state?
I've read this but I'm not sure what my "router" is considered, and if it's typed, how to indicate when I create the state which store type I declare?
Upvotes: 6
Views: 7409
Reputation: 111
Documentation: https://pinia.vuejs.org/core-concepts/plugins.html#typing-plugins
Here is a complete example:
// main.ts
import { createApp, markRaw } from 'vue';
import { createPinia } from 'pinia';
import type { Router } from 'vue-router';
import App from './App.vue';
import router from './router';
declare module 'pinia' {
export interface PiniaCustomProperties {
router: Router;
}
}
const app = createApp(App);
const pinia = createPinia();
pinia.use(({ store }) => {
store.router = markRaw(router);
});
app.use(pinia);
app.use(router);
app.mount('#app');
Upvotes: 7
Reputation: 495
You can try this:
import { useRouter } from 'vue-router';
export const useStoreAuth = defineStore('storeAuth', {
state: () => {
return {
user: {},
} as AuthState;
},
actions: {
init() {
const router = useRouter(); //--> define router here;
onAuthStateChanged(auth, user => {
if (user && user.uid && user.email) {
this.user = { id: user.uid, email: user.email };
router.push('/'); //--> this should work
} else {
this.user = null;
router.replace('/auth');//--> this should work
}
});
},
}
});
It might be a bit inconvenient to define the router in every action if you need to use it, but here's the way I'm using it, you can refer.
Upvotes: -1