Home > Blockchain >  Vue Router fullPath lost on web browser refresh
Vue Router fullPath lost on web browser refresh

Time:10-19

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" />
  • Related