How to use `useRoute`/`useRouter` in a Pinia Store using Setup Store syntax in Vue3?
Asked Answered
H

1

6

I've been trying to get my Pinia store up and running in Vue 3 and it all has been pretty effortless until I wanted to access some parameters in the url.

I have a store (simplified) like so:

import { defineStore } from 'pinia';
import { useRoute } from 'vue-router';
import { useLocalStorage } from '@vueuse/core';

export const useUserStore = defineStore('user', () => {
  const route = useRoute();
  const uuid = ref(
    useLocalStorage('uuid', route.params.id)
  )

 return { uuid };
})

Unfortunately, the route remains undefined as if useRoute() is not triggered properly. I've seen that you can add plugins to add the router instance to the pinia store on initialisation, but there's no way I can find to access that this instance in a Setup Store.

Any help would be greatly appreciated

Habitable answered 14/12, 2022 at 9:0 Comment(2)
I want something similar. I tried using computed properties which works on load but loses reactivity after navigation.Timeserver
I ended up just importing the router from my router/index. That seems to work without issue.Habitable
E
5

route is not defined when the pinia is initiated.

You need to wait a bit.

One way to do this is to call the function when the component is loaded.

export const useUserStore = defineStore('user', () => {
  const route = useRoute();
  const id = ref('');

  const setId = () => {
    id.value = route.params.id as string; // don't need as string if you don't use TypeScript
  };

  return { id, setId };
});
<script setup lang="ts">
import { useUserStore } from '../stores/user';
const user = useUserStore();

user.setId(); // call the function from pinia, route.params works just fine
</script>

Link Demo

Eructate answered 14/12, 2022 at 10:1 Comment(2)
Thanks! Hmm, yeah that could work, but it is kind of verbose and not very elegant imo. That means that every time you want to call the userstore you would have to instantiate the route too, which you then don't use. I foresee that other people will forget that and that it'll cause issues in the long run.Habitable
@RobinG Sorry I forgot to remove the useRoute here. I imported it in the demo link just to show it in the template {{ route.params.id }}. You don't need to call useRoute() if you don't use it in the template. The important part is to call user.setId() on the component that can be accessed when the URL has params.id. If all your routes have it, then just put it in the App.vue.Eructate

© 2022 - 2025 — McMap. All rights reserved.