Reputation: 97
The component which holds q-btn-dropdown
is already rendered before the route change. The route change occurs when the user logs in, so the helloGuest()
is called only once when the component which has the q-btn-dropdown
. So how do I re-render the component which holds the q-btn-dropdown
, so that helloGuest()
is called and the q-btn-dropdown
updates?
methods: {
login() {
this.$axios.post('login', this.formData).then(async (res) => {
console.log(res);
await localStorage.setItem('user', JSON.stringify(res));
await localStorage.setItem('token', res.token);
this.$router.push('/');
}).catch((error) => {
this.error = {
email: error.response.data.message,
};
});
},
<q-btn-dropdown flat dense
:label="helloGuest()"
class="gt-xs"
>
helloGuest() {
const userName = JSON.parse(localStorage.getItem('user')) || {};
console.log('[isauth]', this.isAuthenticated);
console.log('[userName]', userName);
console.log('[router]', this.$router);
if (this.isAuthenticated) {
// this.$forceUpdate();
return `Hello ${userName.username}`;
}
return 'Sign In';
},
my route file looks like this and I havent used mounted hook on the landing route
const routes = [{
path: '/',
component: () => import('layouts/MainDashboard.vue'),
children: [
{ path: '', component: () => import('components/FrontComponent.vue'), meta: { requiresAuth: false } },
{ path: '/product_details/:productId', component: () => import('components/ProductDetails.vue'), meta: { requiresAuth: false } },
{ path: '/cart', component: () => import('../cart/ShoppingCart.vue'), meta: { requiresAuth: false } },
{ path: '/checkout', component: () => import('../cart/CheckoutComponent.vue'), meta: { requiresAuth: false } },
{
path: '/login', name: 'Login', component: () => import('components/LoginComponent.vue'), meta: { requiresAuth: false },
},
{ path: '/register', component: () => import('components/RegisterComponent.vue'), meta: { requiresAuth: false } },
],
Upvotes: 1
Views: 3393
Reputation: 2068
Just make wrapper of your original component and assign the wrapper to the route instead of original component. Like as follows:
<script lang="ts" setup>
import { useRoute } from "vue-router";
import OriginalComponent from "./OriginalComponent.vue";
const route=useRoute();
</script>
<template>
<OriginalComponent :key="route.fullPath"></OriginalComponent>
</template>
Then assign the above to router
{
path: "/some-path/:param",
component: OriginalComponentWrapper,
},
That will lead to re-build of OriginalComponent on any route change, including parameters etc. onMounted of the OriginalComponent will be invoked
Upvotes: 0
Reputation: 97
The best solution seems to be use a watcher to watch $route and call a function on $route change
Upvotes: 0
Reputation: 2109
Vue can reuse the instance, when the component is same, so the this.$route
in the component will change but created()
, beforeMounted()
and mounted()
hooks won't be called.
To force vue to create a new component instance you can set a unique key on the like <router-view :key="$route.fullPath">
Another options is to react to changes in the $route
with a watcher:
watch: {
"$route.params.cname": {
handler(cname) {
// do stuff
},
immediate: true
}
}
Upvotes: 1