Skip to content

Remove existing routes #1234

@alekbarszczewski

Description

@alekbarszczewski

Right now it is possible to dynamically add routes by calling router.addRoutes([/* routes */]). It would be nice if it was possible to also remove/replace routes on the fly. In my app user may define routes by himself (on the fly). I keep user configuration in the Vuex store, and when it is updated I want to completely replace whole router routes configuration (though replacing/removing single route would be also handful but I guess then it should also handle removing/replacing/adding child routes instead of only dealing with top-level routes, which would be quite complicated). I imagine that after replacing routes router would check if current path matches any of the new routes and navigated to it.

It could be for example method router.replaceRoutes([/* routes */]) or router.setRoutes (in addition to method router.addRoutes which already exists).

Please note that this situation can be handled without VueRouter by setting one global route /* that will match every possible path, performing route matching inside this global route component (based on dynamic config stored in Vuex store for example) and dynamic rendering of component(s) that matched current path. However this is very ugly solution which looses all benefits of VueRouter, and handling child routes would be complicated.

In fact I wanted to handle it by patching VueRouter manually, but it seems that createMatcher (https://github.com/vuejs/vue-router/blob/dev/src/create-matcher.js#L16) does not expose pathMap and nameMap so it is not possible modify routes configuration in other way than by calling router.addRoutes (I guess it's intentional :).

Activity

posva

posva commented on Mar 9, 2017

@posva
alekbarszczewski

alekbarszczewski commented on Mar 9, 2017

@alekbarszczewski
Author

In my app user may dynamically set routing. For example he has three predefined components A, B and C; In the application (in browser :) he can manage route configuration; let's say there is a textarea with following JSON:

[{ path: "/my-custom-path", component: "A" }, { path: "/some/other/path/:id", component: "B" }, ...]

For now I can just add new routes to the router:

import A from '@/components/A';
import B from '@/components/B';
import C from '@/components/C';

const allComponents = { A, B, C }; 

// "routes" is array of routes provided by user/client in textarea (textarea is just an example :).
onConfigChanged = routes => {
  routes = routes.map(route => {
    return { path: route.path, component: allComponents[route.component] };
  });
  router.addRoutes(routes);
};

// onConfigChanged is called on each change to configuration by user/client

What I need is to completely replace all routes: router.replaceRoutes(routes) or maybe router.addRoutes(routes, { replace: true }) (it should completely replace routes configuration).

#1129 is close but it won't solve my problem because I don't know route names...

I know that this is not primary use-case for VueRouter, but it would allow to do more advanced things (like my use-case).

ianaya89

ianaya89 commented on Mar 17, 2017

@ianaya89

I like this feature request, I have uses cases where I need to replace url parameters dynamically just to generate a URL to share and grant a unique access for a view with data that I already have in memory (where I don't need view changes or async operations).

nickforddev

nickforddev commented on Apr 12, 2017

@nickforddev

My application has different very routes for different user roles (some are replaced, some should be inaccessible or not exist at all). While it is already possible to achieve this using hooks and basic permissions definitions, I am interested in the idea of replacing the routes entirely on login/logout. The set of routes available could then be unique for each user role, and public/non-authenticated users.

fritx

fritx commented on Jul 1, 2017

@fritx

I had my components depends on the api, and the api now needs to depend on the router,
however, the router has to depend on the components,
because of the new Router({ routes: [{ component }] }) syntax,
which causes a circular require now.

(the resolve => reuqire([path], resolve) syntax doesn't work for me.)

+1 for dynamic routes config, so I can export the router instance first.

added a commit that references this issue on Jul 14, 2017
9dc2c48
deleted a comment from lerit on Sep 18, 2017
deleted a comment from Telanx on Sep 18, 2017
deleted a comment from fancyboynet on Sep 18, 2017
nickforddev

nickforddev commented on Sep 26, 2017

@nickforddev

Is there any intention of implementing this? It felt like there was some momentum on this for a while

52 remaining items

aparajita

aparajita commented on Jun 8, 2020

@aparajita
renatodeleao

renatodeleao commented on Nov 12, 2020

@renatodeleao

Another usecase: oversimplifying a lot for demo purposes but let's say that I have basically 2 apps running while migrating a codebase: legacy(not-vue) to next (vue) and they both map the same urls for user convenience while sharing links in this transition period. So myapp.com/some-page will render either a legacy app view or a next app view based on a user featureFlag (like a beta testing, but remember they use the same url!!) so picture an incremental migration.

// inital router.js
const routes = [...alreadyMigratedNextRoutes] // already battle-tested vue routes no longer under the featureFlag, no more legacy views fallback
const router = new VueRouter({ routes })

// some data fetching work...

if (store.state.curAccount.featureFlag) {
  router.addRoutes(underTestingNextRoutes) // the ones with the same paths as legacy views, now curAccount will get `next` views
} 

// else do nothing (as in navigating to those paths will load the `legacy` app versions
// voilá this works

The problem is that switching accounts on the app (meaning no page reload) and assuming curAccount had featureFlag === true and we switch to account_b has the featureFlag === false, means that I need to remove underTestingNextRoutes from the router routes array so that account_b effectively sees the legacy app view when navigating to that url.

// pseudoCode for some selectbox

onSwitchAccounts(targetAccount) {
  this.$store.dispatch('fetchAccount', targetAccount).then((accountBPayloadj) => {
      this.$store.commit('UPDATE_CUR_ACCOUNT', accountBPayload)
       
      if (accountBPayload.featureFlag === false) {
         // yup would be handy
         this.$router.removeRoutes(underTestingNextRoutes)

        // Now if accountB goes to `myapp.com/some-page`, it should see the `legacy` version.
      }
   })
}
 

Does this make sense on why I can't simply use router hook/guard? In practice i want to redirect... to the same url.

Note that i'm not saying there isn't another way of doing it, and yes "you should just use a next.myapp.com" are expected (reddit) counter-arguments. I'm just trying to express what it seems to be a practical use-case for the feature.

✌️ ☮️

redfox05

redfox05 commented on Nov 25, 2020

@redfox05

@posva It says you added fixed in 4.x but can you link to a commit/documentation so we can know how to use it and close this issue if it solves it?

posva

posva commented on Nov 25, 2020

@posva
Member
deleted a comment from xyfy on Nov 25, 2020
redfox05

redfox05 commented on Nov 26, 2020

@redfox05

@posva Thanks, was hoping for a commit hash or link to documentation, but understand you're probably busy.

For others interested in the information, I managed to find the docs for it here: https://next.router.vuejs.org/guide/advanced/dynamic-routing.html#removing-routes

I was surprised this issue was not linked to a commit when the feature was implemented, and this issue is still Open, so figured it was not fully complete? Hence I tried looking for a commit hash but couldn't find one. Hopefully the docs will be enough for people.

changed the title [-]Feature request: replace routes dynamically[/-] [+]Remove existing routes[/+] on Dec 29, 2020
tomoat

tomoat commented on Apr 6, 2022

@tomoat

Only according to the name to delete the router now? How to delete the router by path?

dakt

dakt commented on Mar 5, 2023

@dakt

Really, how does one remove unnamed route?

gzusgo-thinkbig

gzusgo-thinkbig commented on Jun 9, 2023

@gzusgo-thinkbig

The reason this feature is no only a good idea but a must have, is because the nested routes behave very buggy, every time you go in and out and of the nested child of the route, and the route no even takes you where you want to go instead it take you to the last visited child of the parent.

This make navigation and routing very unpredictable and impossible to work with.

HongYangHT

HongYangHT commented on Apr 3, 2024

@HongYangHT

使用addRoute回调, 可以实现删除路由, 官网查看

const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话

trry-hub

trry-hub commented on May 11, 2024

@trry-hub

使用addRoute回调, 可以实现删除路由, 官网查看

const removeRoute = router.addRoute(routeRecord) removeRoute() // 删除路由如果存在的话

你这个是vue-router 4.x 的,但3.x对应的版本中没有这个方法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestfixed on 4.xThis issue has been already fixed on the v4 but exists in v3group[dynamic routing]Issues regarding dynamic routing support (eg add, replace, remove routes dynamically)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @coxy@dmitry@aparajita@riri@davispuh

      Issue actions

        Remove existing routes · Issue #1234 · vuejs/vue-router