Search code examples
vue.jsvuejs3vue-routervue-composition-api

Vue 3 Composition API useRouter() inside onMounted hook


I want to use useRoute inside my component which is called in onMounted hook. Something like

import { checkUserAuth } from '@/common/CheckUserAuth'

onMounted(async () => {
  await checkUserAuth()
})

And CheckUserAuth.ts is:

import { useRouter } from 'vue-router'

const router = useRouter() // here router is undefined

export const checkUserAuth = async () => {
  const userStore = useUserStore()
  const userApi = new UserApi()
  const token = localStorage.getItem(TOKEN_NAME)

  const router = useRouter() // and here too router is undefined

  if (!token) {
    await router.push({ name: LOGIN_PAGE_ROUTE })

    return
  }

  const userData = await userApi.fetchMasterInfo()
  userStore.setUser(userData)
  await router.push({ name: DASHBOARD_ROUTE })
}

I don't understand why the router is indefined everywhere and is it possible to solve this without passing the router as an argument? (i want to make the checkUserAuth function fully encapsulated)

i know i can fix it like

const router = useRouter()

onMounted(async () => {
  await checkUserAuth(router)
})

export const checkUserAuth = async (router: Router) => {
  await router.push({ name: DASHBOARD_ROUTE })
}

But it's not good solution


Solution

  • The API of useRouter must be called in setup, as mentioned in the official document. You can see this point in https://router.vuejs.org/zh/api/#userouter(zh document mentioned it). Maybe you can write code like this:

    import { useRouter } from 'vue-router'
    
    export const useCheckUserAuth = () => {
      const userStore = useUserStore()
      const router = useRouter()
    
      return async function checkUserAuth() {
        const userApi = new UserApi()
        const token = localStorage.getItem(TOKEN_NAME)
        if (!token) {
          await router.push({ name: LOGIN_PAGE_ROUTE })
      
          return
        }
      
        const userData = await userApi.fetchMasterInfo()
        userStore.setUser(userData)
        await router.push({ name: DASHBOARD_ROUTE })
      }
    }
    

    And call it in setup:

    const checkUserAuth = useCheckUserAuth()
    
    onMounted(() => {
      checkUserAuth()
    })
    

    hope it can help you.