Should be possible to set route name
to undefined
#565
Replies: 3 comments 1 reply
-
Why are you trying to remove the name from the page? Is this just a convenience thing? |
Beta Was this translation helpful? Give feedback.
-
Hi @posva 😀 From my original question on discord:
maybe i'm doing something wrongly. But removing the parent route name works. Repo: https://github.com/ricardo17coelho/vue-router-unplugin-breadcrumbs |
Beta Was this translation helpful? Give feedback.
-
I'm interested in some more clarification on this issue, maybe just for the sake of figuring out if I am on the path to some sort of anti-pattern here. The structure here is a parent route with a component, where the route does not make sense without a child also being rendered inside the parent. Like a settings page which may just be a menubar/tabs type thing, and each settings panel being a separate page rendered as a child. Settings is a component, but it would just mostly be an empty page without any specific settings being rendered. Maybe we would have some general settings as index.vue or (general).vue, and we would never want the settings component to render without that, or some specific other settings page. As I understand today, you would end up with route names (and the following type hints) for '/settings' and '/settings/' (or '/settings/(general)'), where the first one would render an "empty" settings page. I may be wrong, but currently there is no way to change this and still having it reflect in the actual exported types from the plugin? I have included the getRouteName I am experimenting with now, with a long comment, mostly just for rubber ducking, but it may illustrate my issue. Thanks for any more information on the topic, as the use case for component routes without names is specifically mentioned in the vue router docs: https://router.vuejs.org/guide/essentials/nested-routes.html#Nested-Named-Routes getRouteName: (routeNode) => {
// Given a desired simple layout structure like this:
//
// PATH: /claims/foo PATH: /claims/foo/resources
// NAME: '/claims/[id]' * NAME: '/claims/[id]/resources'
// ┌─────────────────────┐ ┌───────────────────┐
// │ [id].vue (foo) │ │ [id].vue (foo) │
// │ ┌─────────────────┐ │ │ ┌───────────────┐ │
// │ │ index.vue │ │ ────────────> │ │ resources.vue │ │
// │ │ or (bar).vue │ │ │ │ │ │
// │ │ but never empty │ │ │ │ │ │
// │ └─────────────────┘ │ │ └───────────────┘ │
// └─────────────────────┘ └───────────────────┘
//
// * Trailing slash or not is not that important, but we just want a
// consistent name for the "default child route". With different
// "default" children using route groups, it could get a little
// inconsistent though (e.g. '/claims/[id]/(foo)' and
// 'user/[id]/(baz)', when we always mean the default child /
// index, i.e. /claims/[id] or /users/[id]).
//
//
// The current situation with (named) file based routing (all routes with components must have names?):
//
// FOLDER STRUCTURE | PATH. | NAME
// | |
// src/pages/claims | |
// ├── index.vue | claims (/claims) | '/claims'
// ├── [id].vue | :id (/claims/:id) | '/claims/[id]' *
// └── [id]/ | |
// ├── index.vue | '' (/claims/:id) | '/claims/[id]/' **
// ├── resources.vue | calednar (/claims/:id/resources) | '/claims/[id]/resources'
// └── ... | ... (/claims/:id/...) | '/claims/[id]/...'
//
// * This is the main issue; this route name only serves as
// confusion for us. Navigating to this name, gives us [id].vue,
// without any child rendered. If we then reload the page we get
// [id].vue with index.vue as the rendered child, because they
// "share the same path" (index.vue has an empty path). It would
// be nice if this name would not exist, or at least not show up
// in the type hits, so we don't accidentally use it in the code.
// ** This route name gives us what we want, i.e. loading [id].vue
// with index.vue as a child, both on navigation and reload.
//
//
// What I think we want, is unnamed routes for parents which should
// always render with a child, either "index.vue" or a group named
// child like "(details).vue" (Vue router docs mentions this use
// case specifically at
// https://router.vuejs.org/guide/essentials/nested-routes.html#Nested-Named-Routes):
//
// FOLDER STRUCTURE | PATH | NAME
// | |
// src/pages/claims | |
// ├── index.vue | claims (/claims) | '/claims'
// ├── [id].vue | :id (/claims/:id) | *
// └── [id]/ | |
// ├── index.vue | '' (/claims/:id) | '/claims/[id]' **
// ├── resources.vue | calednar (/claims/:id/resources) | '/claims/[id]/resources'
// └── ...vue | ... (/claims/:id/...) | '/claims/[id]/...'
//
// * As we cannot remove the name without forking the plugin or
// something similar, we add a suffix to indicate that this route
// name should probably not be used directly.
// ** We remove any trailing slash / renamed index segment (either
// index.vue, or any parenthesed file name like (details).vue)
// for convenience, because we want the "index" child to be
// always rendered.
// This step is not necessary, and may be logically wrong in
// terms of the relationship between paths and names.
// Maybe it makes more sense with simpler names like "foos",
// "foo", "foo-resources", where we want a name for a "default
// route for a single thing", but still want that route to always
// render its index child, regardless if its index child is
// index.vue or (details).vue or something else.
const fileBasedRouteName = getFileBasedRouteName(routeNode)
let hasIndexChildRoute = false
routeNode.children.forEach((child) => {
if (child.value.rawSegment === 'index' || /^\(.*\)$/.test(child.value.rawSegment)) {
hasIndexChildRoute = true
}
})
if (hasIndexChildRoute) {
return fileBasedRouteName + '(DO-NOT-USE)' // Returning void/null/undefined here names the route 'undefined' etc
}
const isIndexRoute =
routeNode.value.rawSegment === 'index' || /^\(.*\)$/.test(routeNode.value.rawSegment)
if (isIndexRoute) {
return fileBasedRouteName.replace(/\/\([^)]+\)$|\/$/g, '')
}
return fileBasedRouteName
}
}) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In order to match this case: https://router.vuejs.org/guide/essentials/nested-routes.html#Nested-Named-Routes
Where the parent route name should not be defined, it should be possible to defined the route name as
undefined
definePage({
....
name: undefined,
....
});
This works but theres is an warning in the console & should be the case:
⚠️ [unplugin-vue-router]: route name must be a string literal. Found in "/path/file_01.vue".
⚠️ [unplugin-vue-router]: route name must be a string literal. Found in "/path/file_02.vue".
⚠️ [unplugin-vue-router]: route name must be a string literal. Found in "/path/file_03.vue".
i "reported" this as well here: https://discord.com/channels/325477692906536972/325479452773580800/1298912972734992405
but no reactions so far..
Beta Was this translation helpful? Give feedback.
All reactions