Versions:
"dependencies": {
"@types/node": "^16.7.4",
"core-js": "^3.6.5",
"vue": "^3.0.0",
"vue-class-component": "^8.0.0-0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
},
So I've been building an SPA online portfolio in Vue3 and I've been faced with this problem since the beginning. I use the current route to trigger a transition on my HeaderComponent. That part's not important, really.
Whenever I navigate to /
, this.$route.fullPath
looks normal.
However, if I go to one of the other routes on my app, for example /webdev
, and then I refresh, and check this.$route.fullPath
again, it has /
instead of /webdev
like I expected it would.
So, as long as I don't refresh, the Header transition works as intended; however, the second I refresh on a route that isn't /
, Vue Router forgets where I was and instead thinks I'm at the base path /
.
src/router/index.ts
import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
import WebDev from '../views/WebDev.vue';
import SoundDesign from '../views/SoundDesign.vue';
export default createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/webdev',
name: 'Web Dev',
component: WebDev,
},
{
path: '/sounddesign',
name: 'Sound Design',
component: SoundDesign,
},
{
path: '/:catchAll(.*)*',
name: 'Home',
component: Home,
}
],
});
src/App.vue
<template>
<div class="page-container">
<div class="content">
<HeaderComponent :condenseHeader="condenseHeader"></HeaderComponent>
<main>
<router-view v-slot="{ Component }">
<transition
name="fade"
mode="out-in"
@before-leave="beforeLeave"
appear
>
<component :is="Component"></component>
</transition>
</router-view>
</main>
</div>
<FooterComponent></FooterComponent>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import HeaderComponent from './components/HeaderComponent.vue';
import FooterComponent from './components/FooterComponent.vue';
export default defineComponent({
name: 'App',
components: {
HeaderComponent,
FooterComponent,
},
data: () => ({
condenseHeader: false,
}),
beforeMount() {
this.setCondenseHeader();
},
methods: {
beforeLeave() {
this.setCondenseHeader();
},
setCondenseHeader() {
this.condenseHeader = this.pathNotHome;
},
},
computed: {
pathNotHome() {
return this.$route.fullPath !== '/';
},
},
});
</script>
I've already tried both types of History in the routes file, as I've read that the HTML5 Browser History mode can cause 404's with things on reload, but I'm not getting a 404 - the page content remains as it did before the reload, but this.$route
seems to reset or error out, or something.
Unless I'm doing something wrong, I'm surprised this is a bug in Vue as of now.
CodePudding user response:
I think the problem is all to do with timing.
You're setting condenseHeader
initially in your App
component beforeMount
hook. My guess is that when this hook fires on initial page load, the route path has not been resolved.
What I would do instead is make condenseHeader
reactive by making it a computed property
computed: {
condenseHeader () {
return this.$route.fullPath !== '/';
}
}
Also, as per Prop Casing (camelCase vs kebab-case), your condenseHeader
attribute should be condense-header
...
<HeaderComponent :condense-header="condenseHeader" />