Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue Router route query param added by beforeEnter lost after navigate into the same route

When navigating into the same route you are currently at, the route query page added by the before enter route guard is lost.

This is due to the fact that router link to object does not contain query page, and it does not go into before enter hook anymore, since it is already in the same route.

I figured out that you can add it in your router push or link button and you need to add this whenever you know the view contain query page.

Example:

this.$router.push({ name: 'routeName', query: { page: 1 } });

Question:

Is there an elegant way to handle this in route guard?

Which hook should I use so that route query page can be kept even user navigate into the same route?

Example code:

Route

// Sample route
const routes =  [
  {
    path: 'test',
    name: 'Test',
    component: TestPage,
    beforeEnter: testPageGuard,
  },
];

Route Guard

// Test Page Guard
testPageGuard: (to, from, next) => {
  const { page = null } = to.query;  
  let finalNext;

  if (!page) {
    finalNext = {
      ...to,
      query: {
        ...to.query,
        page: 1,
      },
    };
  }

  if (finalNext) {
    next(finalNext);
  } else {
    next();
  }
}

View

// TestPage.vue
<template>
  <!-- The problem can be reproduce when clicking this link 
       when you are already in route '/test'               -->
  <router-link :to="{ name: 'Test'}">
    Test
  </router-link>
</template>

<script>
export default {
  name: 'Test',
};
</script>

Solution Figured:

  • Add query page to router link
// TestPage.vue
<template>
  <!-- query page is added here -->
  <router-link :to="{ name: 'Test', query: { page: 1 } }">
    Test
  </router-link>
</template>

<script>...</script>
like image 364
Darky WC Avatar asked Oct 16 '25 21:10

Darky WC


1 Answers

I figured out that there are two more ways to do this.

Solution 1: Update at "beforeRouteUpdate" Hook

beforeRouteUpdate triggers when query param changes even when in the same route.

Hence we can remove the beforeEnter guard and the extra page query in the route link, and do query param page adding at that particular page.

Example Code

View

// TestPage.vue
<template>
  <!-- The problem can be reproduce when clicking this link 
       when you are already in route '/test'               -->
  <router-link :to="{ name: 'Test'}">
    Test
  </router-link>
</template>

<script>
export default {
  name: 'Test',

  // Solution here
  beforeRouteUpdate(to, from, next) {
    if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
      next({
        ...to,
        query: {
          // This line is used to retain other query if there is any
          ...to.query,
          page: 1,
        },
      });
    } else {
      next();
    }
  },
};
</script>

Solution 2: Update at "beforeEach" Hook

When query param changes even when in the same route, it actually go through beforeEach hook also.

Hence we can remove the beforeEnter guard and the extra page query in the route link.

Add meta tag hasQueryParamPage for that route and do query param page adding in the global beforeEach hook.

This design has better reusability if you have other pages that require the query param page.

Example Code

Route

// Sample route
const routes =  [
  {
    path: 'test',
    name: 'Test',
    component: TestPage,
    // add meta tag
    meta: { hasQueryParamPage: true },
  },
];

Router

// router.js
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
...
});

// Solution here
router.beforeEach((to, from, next) => {
  if (to.matched.some((record) => (record.meta.hasQueryParamPage))) {
    let updatedNext = null;

    if (!Object.prototype.hasOwnProperty.call(to.query, 'page')) {
      updatedNext = {
        ...to,
        query: {
          // This line is used to retain other query if there is any
          ...to.query,
          page: 1,
        },
      };
    }
    
    if (updatedNext) {
      next(updatedNext);
      return;
    }
  }

  next();
});
like image 86
Darky WC Avatar answered Oct 18 '25 14:10

Darky WC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!