3

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

3 Answers 3

7

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>
Sign up to request clarification or add additional context in comments.

Comments

0

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>

2 Comments

I tried all manner of this.$router but always get Property '$router' does not exist :(
Are you using vue-router as plugin ? If not i will update my answer
0

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

1 Comment

What if you want this to be in another child component and not in App.vue?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.