Given is a VueJS 3 application, based on Quasar and I am struggling to use the Router programmatically.
The issue is described best like this:
1. The Problem
When I push the User to another route, only the URL in the browser will be updated, but the corresponding Component will not get rendered.
I have to manually refresh the web page in the Webbrowser in order to get the corresponding component rendered properly.
2. Code
I have published a full working example on GitHub: https://github.com/itinance/quasar-
router-bug
The router is configured in history-mode, but this doesn’t matter as the issue appears also in the hash-mode.
Here are my routes:
import { RouteRecordRaw } from 'vue-router';
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
},
{
path: '/test',
name: 'test',
component: () => import('layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('pages/TestPage.vue') }],
},
// Always leave this as last one,
// but you can also remove it
{
path: '/:catchAll(.*)*',
component: () => import('pages/ErrorNotFound.vue'),
},
];
export default routes;
Here is my Index-Component, that contains a button where I want to send the user programmatically to another page:
<template>
<q-page class="row items-center justify-evenly">
<div class="q-pa-md example-row-equal-width">
<div class="row">
<div>INDEX PAGE</div>
</div>
<div class="row">
<div>
In order to navigate to the test page, you need to manually reload the page after clicking the button.
Otherwise, only a white page will be rendered.
<q-btn align="left" class="btn-fixed-width" color="primary" label="Go to test page" @click="doRedirect"/>
</div>
</div>
</div>
</q-page>
</template>
<script lang="ts">
import {Todo, Meta} from 'components/models';
import ExampleComponent from 'components/ExampleComponent.vue';
import {defineComponent, ref} from 'vue';
import {dom} from 'quasar';
import {useRouter} from 'vue-router';
export default defineComponent({
name: 'IndexPage',
computed: {
dom() {
return dom
}
},
components: {},
setup() {
const router = useRouter();
const doRedirect = () => {
console.log('doRedirect');
router.push({name: 'test'});
}
return {doRedirect};
}
});
</script>
And this is the test-component, which is the target component where I want to use send:
<template>
<q-page class="row items-center justify-evenly">
<div class="q-pa-md example-row-equal-width">
<div>
TEST PAGE
this will only be rendered after manual page-reload
</div>
</div>
</q-page>
</template>
<script lang="ts">
import { Todo, Meta } from 'components/models';
import ExampleComponent from 'components/ExampleComponent.vue';
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'TestPage',
setup () {
return { };
}
});
</script>
- What happens instead?
3.1 This is the index page, containing the button that shall send the user to another page:
3.2. When I click on the Button, the URL will be updated correctly but the test-component won’t get rendered at all:
3.3. But when I refresh the web browser now manually (or navigate to that particular URL), it will render the test component:
#4. Question
What am I doing wrong? How can I programmatically send the user to the test-page so that not only will the URL be updated but also the component will get rendered automatically, once the URL has changed?
As already mentioned, I also published a small test project that makes the described issue reproducible: https://github.com/itinance/quasar-router-bug