I have a simple Vue router setup from Laravel. I am trying to add a wildcard route because of a component that I will be using needs it. My Routes are:
import Dashboard from '#/components/Dashboard'
import MyFiles from '#/components/MyFiles'
import Error403 from '#/components/Error403'
import Error404 from '#/components/Error404'
export default [
{
name: 'index',
path: '/',
redirect: {
name: 'dashboard',
}
},
{
name: 'dashboard',
path: '/dashboard',
component: Dashboard,
props: true,
},
{
name: 'files',
path: '/dashboard/files/*', //Note the wildcard here.
component: MyFiles,
props: true,
},
{
name: '403',
path: '/403',
component: Error403,
},
{
name: '404',
path: '/404',
component: Error404,
},
{
name: 'catch-all',
path: '*',
component: Error404,
},
]
Everything appears to work. But when I click on my router-link for 'files' route. It goes to / and does not redirect but shows the files components. Very confusing...
Additionally I have this error in console:
[vue-router] missing param for named route "files": Expected "0" to be defined
Has anyone ran into this problem? Im very stumped as what to do. Any direction would be appreciated.
ADDITIONALLY
Here is the router-link that is the problem. Note that this is in a Blade File. the params are just strings.
<router-link
class="nav-link"
exact-active-class="active"
:to="{ name: 'files', params: { endpoint: '{{ route('myFiles') }}', endpointget: '{{ route('myFiles.get') }}' } }"
>
{{__('My Files')}}
</router-link>
Please reorder your routes.
The two last routes needs to be this
[{path: '/404'}, {path: '/'}, {path: *}]
From the more especific, to the more generic, thats it the correct match.
Next, i think if you remove "name" in the route * or in files route maybe fix the problem.
Related
Explanation: I have App.vue, Management.vue, Login.vue and Register.vue pages. And I have another folder saying management_pages. In that management folder I have Products.vue and Suppliers.vue files.
What I'm expecting to do: In the App.vue I want the router-view to be for Management.vue, Login.vue and Register.vue only. And when we go to my /management route I want the router-view to be Products.vue (/products) and Suppliers.vue (/suppliers) since the layout of both files are in my Management.vue file. How can I handle such thing?
I have tried this:
import { createRouter, createWebHistory } from "vue-router";
import Products from "../pages/Products.vue";
import Suppliers from "../pages/Suppliers.vue";
import ErrorPage from "../pages/ErrorPage.vue";
import Login from "../pages/Login.vue";
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/products",
name: "Products",
component: Products,
},
{
path: "/suppliers",
name: "Suppliers",
component: Suppliers,
},
{
path: "/:pathMatch(.*)*",
name: "ErrorPage",
component: ErrorPage,
},
{
path: "/login",
name: "Login",
component: Login,
},
],
});
export default router;
As stated in the comments, your question is vague, but since you are struggling I will try provide an answer. If I understand your question correctly, you want to define nested routes for /management/products and /management/suppliers.
First you need to add a <router-view></router-view> to your Management.vue component, where you want the content of Products.vue and Suppliers.vue.
Then you need to define the products and supplier routes as children of the management route, like:
routes: [
{
path: "/management",
name: "Management",
component: Management,
children: [
{
path: "products",
name: "Products",
component: Products,
},
{
path: "suppliers",
name: "Suppliers",
component: Suppliers,
},
]
},
{
path: "/login",
name: "Login",
component: Login,
},
{
path: "/:pathMatch(.*)*",
name: "ErrorPage",
component: ErrorPage,
},
],
Be sure to also import the Management.vue in your router file.
If you don't want /management to be a accessible route, you can define a redirect on the /management path to one of the children, like:
redirect: { name: 'Products' }
Hope this helps.
Given the following route:
{
path: '/detail/:someId',
component: SomeDetailComponent,
name: 'some-detail',
children: [
{
path: 'dashboard',
component: DashboardComponent,
name: 'dashboard'
},
{
path: '',
redirect: { name: 'dashboard' }
},
{
path: 'other',
component: OtherComponent,
name: 'other'
}
]
},
Why does this work (the dashboard component is visible):
this.$router.push(`/detail/123/`);
But this doesn't:
this.$router.push({name: 'some-detail', params: { someId: 123 }});
In one case, the URL gets a trailing slash while in the other it doesn't. I've read somewhere in the docs that this is a breaking change coming from Vue2. See:
named-children-routes-with-an-empty-path-no-longer-appends-a-slash
So the real question here could be: how can I still have my working child navigations (with redirection) while still being able to navigate using the route name, instead of the route url part.
I have my routes as define below:
const router = new Router({
base: '/',
mode: 'history',
routes: [
{
path: '/',
redirect: `${DEFAULT_LOCALE}`,
},
{
path: '/:locale?',
component: AppTemplate,
children: [
{
path: 'home',
name: 'home',
component: () => import('#/views/Home.vue'),
meta: {
title: 'Home',
}
}
{
path: 'about',
name: 'about',
component: () => import('#/views/About.vue'),
meta: {
title: 'About',
},
},
{
path: 'contact',
name: 'contact',
component: () => import('#/views/Contact.vue'),
meta: {
title: 'Contact',
},
},
{
path: '*',
redirect: { path: '/' },
},
],
},
{
path: '*',
redirect: { path: '/' },
},
],
});
export default router;
I use :locale for app translation. It is optional because empty locale is for default language. My problem here is even if locale is present, all the links to other pages are without the locale, if that makes sense. For eg, example.com/about is in Italian and example.com/en/about is in English. But which ever URL it is, the links present on the page always points to contact or home page as example.com/contact and example.com/home. Is there a way to fix this? Or is there an easier way to use app translation from URL. I am using vue-i18n for the translation. Thanks
For such configuration I think you have to pass param to make it work:
<router-link :to="{name: 'contact', params: {locale: $route.params.locale} }">
https://jsfiddle.net/3gx4hak5/
Also maybe router-link append attribute will do the trick for you: https://router.vuejs.org/api/#append
Setting append prop always appends the relative path to the current path. For example, assuming we are navigating from /a to a relative link b, without append we will end up at /b, but with append we will end up at /a/b.
<router-link :to="{ path: 'relative/path'}" append></router-link>
My App works just fine, if I put routes without childrens (nesting) but I tried to nest it just now and converted my routes to this: in routes.js
import alphabetsPage from './components/views/pages/alphabets.vue'
import dictionaryPage from './components/views/pages/dictionary.vue'
import numbersPage from './components/views/pages/numbers.vue'
import LayoutView from './components/views/Layout.vue'
const routes = [{
path: '/',
name: 'Home',
component: LayoutView,
children: [{
path: 'basic',
name: 'Basic',
component: alphabetsPage,
children: [{
path: 'alphabets',
name: 'Aphabets',
component: alphabetsPage
},
{
path: 'numbers',
name: 'Numbers',
component: numbersPage
}]
}]
}]
export default routes
If I go to / or click on route <router-link to="/basic/alphabets" tag="li"><a>numbers</a></router-link> I can see the alphabetsPage component, however if I go click on <router-link to="/basic/numbers" tag="li"><a>numbers</a></router-link> the route doesn't work. I have a numbersPage componet working.
This must be from the routes, because, if I don't use children and just define the path in routes as /basic/numbers or /basic/alphabets it works.
Children should be shown somewhere.
Your alphabetsPage do not have in template
const alphabetsPage = {
template: '<div>/basic/alphabets <router-view></router-view></div>'
}
https://jsfiddle.net/6fvL1xwc/
I'm trying to have a homepage with tabs containing 2 lists, with 1 open by default.
I have the following route config, I've changed the names to simplify
let routes = [{
path: '/',
name: 'home',
component: require('./views/Home.vue'),
children: [{
path: 'list1',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
Inside ./views/Home.vue I have a <router-view></router-view> below 2 <router-link>s for each tab (child route).
When I visit the app route http://domain/ I would like to activate the list1 tab. The only way I can currently do this is if I visit http://domain/list1.
I have tried
children: [{
path: '',
name: 'home.list1'
and this initially works well, however if I visit http://domain/list2 both my tab links (router-links) have the active state.
JSFiddle which I can't get to run but helps for context
Is there a better solution to this?
Add one more child route with redirect (should be first)
children: [{
path: '',
redirect: 'list1', // default child path
},
...
]
For making a component(tab) appear default at visiting the parent route, you need to add a path as '' (empty string)
The following is a n example from the Vue Router docs
const router = new VueRouter({
routes: [
{
path: '/user/:id', component: User,
children: [
// UserHome will be rendered inside User's <router-view>
// when /user/:id is matched
{ path: '', component: UserHome },
// ...other sub routes
]
}
]
})
Don't use a '/', it will be considered as the root route.
You need to put the redirect on the parent, and it works on the first load.
Otherwise, it only works when I reload the page.
put redirect: 'home.list1' on the parent
put your child as path: ''
hope it works.
let routes = [{
path: '/',
name: 'home',
redirect: {name: 'home.list1'}, // Redirect to named route
// redirect '/list2' // Or redirect to path
component: require('./views/Home.vue'),
children: [{
path: '',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
I think what you want to do works if your home route isn't "/"
routes: [
{ path: '/home',
name: 'home',
component: require('./views/home.vue')
children: [
{ path: '/', name: 'list1', component: list1 },
{ path: 'list2', name: 'list2', component: list2},
],
}
]
This will load the home component and the list1 component inside of your initial . Then you can user router link to nav to list2:
<router-link :to="{ name: 'list2', params: { ...}}">
Or, maybe I don't understand the question.
Here is what works.
You have to use redirect: {name: 'home.list1'} (for the named route) property on your parent route 'home'.
Make sure you use the correct redirect property format either for named route (as above) or for path: redirect: '/list1'.
Here is the correct routes config which is only 1 line (the redirect one) different vs your config:
let routes = [{
path: '/',
name: 'home',
redirect: 'home.list1',
component: require('./views/Home.vue'),
children: [{
path: 'list1',
name: 'home.list1',
component: require('./views/List1.vue')
}, {
path: 'list2',
name: 'home.list2',
component: require('./views/List2.vue')
}]
}
Then every visit to / (your 'home' route) would be redirected to /list1.
Moreover, the router-link-active and router-link-exact-active will be correctly assigned on child link (both of them) and on parent link (only router-link-active).
This will also work for deeper nested non-child and child routes.
For more redirect & aliasig options see the official docs.