Home » vue » How to programmatically route inside a component – Vue Router

How to programmatically route inside a component – Vue Router

Posted by: admin November 26, 2021 Leave a comment

Questions:

I have a Quasar app running Vue 3 with vue-router 4

My routes are setup and work great when navigating from a component template with

<router-link to="/route">Go to route</router-link>

I want to be able to access the router and route from my methods though. According to the docs I should be able to get access to the router object somehow, this.$router, or router, or some other way… but I can’t seem to gain access

My entire single file component looks something like

  <template>
    <q-page>
      <q-card>
        <q-form @submit="handleSubmit()" >
          <q-input v-model="param" />
          <q-btn label="submit" type="submit" />
        </q-form>
        <router-link to="/">Go to Foo</router-link> <!-- this works great -->
      </q-card>
    </q-page>
  </template>

  <script lang="ts">
  import { ref } from 'vue'

  export default {
    setup () {
      const param = ref(null);
      return { param }
    },
    methods: {
      async handleSubmit () {
         // do stuff
         // route somewhere
      }
    }
  }
  </script>

How can I access the vue router from my handleSubmit method?

this.$route and this.$router are undefined, and as I understand with vue 3 and sfc this pattern doesn’t apply. For my store for example I need to use vuex mapState and mapActions

Answers:

Type inference for the Options API requires declaring components with the defineComponent() wrapper:

To let TypeScript properly infer types inside Vue component options, you need to define components with defineComponent global method:

import { defineComponent } from 'vue'

const Component = defineComponent({
  // type inference enabled
})

If you’re using single-file components then this would typically be written as:

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  // type inference enabled
})
</script>

So your component should look similar to this:

<script lang="ts">
import { defineComponent } from 'vue'
                    
export default defineComponent({
  methods: {
    async handleSubmit () {
      // ✅
      this.$router.push('/')
    }
  }
})
</script>

Alternatively, you can use useRouter() in the Composition API:

<script lang="ts">
import { ref, defineComponent } from 'vue'
import { useRouter } from 'vue-router'

export default defineComponent({
  setup() {
    const router = useRouter()
    const handleSubmit = async () => {
      router.push('/')
    }

    return { handleSubmit }
  }
})
</script>

###

Try this

<template>
    <q-page>
      <q-card>
        <q-form @submit="handleSubmit()" >
          <q-input v-model="param" />
          <q-btn label="submit" type="submit" />
        </q-form>
        <router-link to="/">Go to Foo</router-link> <!-- this works great -->
      </q-card>
    </q-page>
  </template>

  <script lang="ts">
  import { ref } from 'vue'

  export default {
    setup () {
      const param = ref(null);
      return { param }
    },
    methods: {
      async handleSubmit () {
         this.$router.push('/link/to/go/anywhere') <-- here
      }
    }
  }
  </script>

###

do you forgot to set the router-view –> tag it should be in App.vue in your template so it render your component data into your router and yes use this.$router.push({ path: ‘your router path‘ }) in your method