I want to build a vue application with many modules. Lets say for an online shop we need modules for customers, products, stock inventory, orders, invoices. For every model we need CRUD functions (and some more).
I would prefer a structure, where I have a component for each these modules. And each module component has sub components for list, create, update, read, delete.
|- products/
| |- index.vue
| |- list.vue
| |- add.vue
| |- edit.vue
| |- view.vue
| |- delete.vue
|- customers/
| |- index.vue
| |- list.vue
| |- ...
How can I define the sub routes (children) for each module in the module (index.vue) itself and not in the main router file? Later I want to be able to share certain URLs like
https://domain.tld/products/view/12345
https://domain.tld/products/edit/12345
It can easily be done. Although it could be discussed whether it should be done or not - it does not really change anything, except possibly reducing the verbosity of the main router file. (In any case, the router definition must have all routes in it, so the difference is merely on the aesthetic side)
Routes are simply Javascript objects - why not doing it like below
In index.vue
const productRoutes = [
{
name: 'view',
path: 'view',
component: productView
},
{
name: 'add',
path: 'add',
component: productAdd
},
{
name: 'edit',
path: 'edit',
component: productEdit
},
]
in the router file
const routes = [
{
name: 'products',
path: '/products',
component: products,
children: productRoutes
}
]
const myRouter = new VueRouter({
routes
})
You need to of course add the appropriate import statements - you'll need
these anyway as the router always needs a reference to the components listed.
Components will then simply be defined by their option object, shown as productAdd, productView, productEdit above.
Related
Migration guide says:
Named children routes with an empty path no longer appends a slash
his has an important side effect about children redirect records like these:
const routes = [
{
path: '/parent',
component: Parent,
children: [
// this would now redirect to `/home` instead of `/parent/home`
{ path: '', redirect: 'home' },
{ path: 'home', component: Home },
],
},
]
Notice:
// this would now redirect to /home instead of /parent/home
But I would like to redirect to /parent/home instead of /home
Docs:
https://router.vuejs.org/guide/migration/#named-children-routes-with-an-empty-path-no-longer-appends-a-slash
So how can one achieve original behaviour before this change with new router? I would like to have relative redirect to a child.
Vue2 playground it works as expected.
Vue3 playground broken by change.
I have a route setup where there's a parent with child routes, like this:
{
//name: 'ProductComments',
path: 'comments',
children: [
{
name: 'ProductComments',
path: '',
component: ProductComments
},
{
name: 'EditProductComment',
path: ':commentId/edit',
component: EditProductComment
}
]
}
With the above configuration, Vue Router will render my ProductComments component if I visit /comments. However, if I comment the name out and uncomment it on the parent, it won't render the ProductComments component and will give me the warning:
The route named "ProductComments" has a child without a name and an empty path. Using that name won't render the empty path child so you probably want to move the name to the child instead. If this is intentional, add a name to the child route to remove the warning.
But why is this? The child is always a more "specific" route, so why does giving it a name magically cause it to render, whereas giving the name to the parent stops it?
I think this is one of those things that was decided by the Vue team and only they can really answer why. I was curious about it though and found this
github thread talking about the exact same thing. Doesn't seem like a satisfactory answer was ever found but the comment I specifically linked contains a workaround which is just adding a redirect:
{
path: '/user/:id',
name: 'user',
/* Explicitly tell the router to redirect to default children */
redirect: '/user/:id/',
component: User,
children: [
{
path: '',
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}
Set everything in the parent; it makes more semantic sense too.
My parent/child routes function like this. I haven't had any problems with this (so far?).
{
name: 'ProductComments',
path: 'comments',
component: ProductComments
children: [
{
name: 'EditProductComment',
path: ':commentId/edit',
component: EditProductComment
}
]
}
This question already has an answer here:
Vue 3 router - router-link-active not working
(1 answer)
Closed 6 months ago.
I am currently in my Vue learning journey. I have come across a situation where I need to show my link as active for matching route too. For example: I have route /programs which shows Program link as active without any issues but I also want /programs/view to set Program link as active as well. How do I do it in Vue Router?
These are my route definitions in router.js file
const routes = [
{ path: '/', component: Main, name: 'main', redirect: '/dashboard', children:
[
{ path: '/dashboard', component: Dashboard, name: 'dashboard' },
{ path: '/programs', component: Programs, name: 'programs' },
{ path: '/programs/view', component: ViewProgram, name: 'view_program'},
...OTHER ROUTES
]
},
{ path: '/login', component: Login, name: 'login', meta: {noAuth: true} },
{ path: '/:pathMatch(.*)*', redirect: '/dashboard'}
];
I searched and found that router-link-active class should be automatically applied to Program link when the route starts with /programs, but it is not working in my case.
EDIT
I have found a workaround by manually matching route and appending active class to the router link. But I still expect an easier way to do this.
In my Program link:
<router-link to="/programs" :class="{'router-link-active': $route.fullPath.match(/\b\programs/) }">
<span>Programs</span>
</router-link>
I am using regex to match path pattern. So, every route that contains programs will get active class here.
dont u gotta do that in the component and not in the router?
take what i say with a grain of salt im
PROBLEM DESCRIPTION
I am using vue develop a multi-entries app, the project folder is some like:
|- assets
| |- fonts
| | |- a.ttf
| |- styles
| | |- b.css // import ../fonts/a.ttf
|- src
| |- page_one
| | |- App.vue // import ../../assets/styles/b.css
Above project runs well in local deleopment enviroment, but reported 404 for the .ttf resource after deployed on the server. I checked the built product, found that the css font url is incorrect: I got http://<host>/css/fonts/a.ttf, while http://<host>/fonts/a.ttf is the expected URL.
TRACK the CAUSE
After lots of survey, I found above problem is related to the page entry. Since I got a lot pages, and I wanted to separate them into different folders, so the entries are some like:
// vue.config.js
module.exports = {
pages: {
'a/one': {
filename: 'a/one.html',
},
},
};
After built, the folder is like:
|- dist
| |- css
| | |- a
| | | |- one-<hash>.css // import ../fonts/a.ttf
| |- fonts
| | |- a.ttf
ROOT REASON: The pack tool (webpack) output css file in subfoler a/one-<hash>.css, while the url in css file is incorrect. Looks webpack supposed css file is directly placed at css folder.
SOLUTION: DO NOT USE / IN ENTRY. A correct configuration file is like:
// vue.config.js
module.exports = {
pages: {
'a-one': { // JUST DO NOT USE SLASH.
filename: 'a/one.html', // You can use this to build the produced pages intro separate folders
},
},
};
After all, if you use webpack and meet same problem, the reason and solution should be same.
Remove the '/' from the page entry. Correct:
// vue.config.js
module.exports = {
pages: {
'a-one': { // JUST DO NOT USE SLASH.
filename: 'a/one.html', // You can use this to build the produced pages intro separate folders
},
},
};
I want to open the same page but by using two different routes. The issue is when clicking on link 1 and after that click on link 2 my page is not being refreshed, when I print this.$route it shows old route info. How to solve this issue?
Link 1 - http://localhost:8080/test1route
Link 2 - http://localhost:8080/test2route
import TestComponent from '#/Component/TestComponent'
export default [{
path: '/test1route',
component: TestComponent,
children: [{
path: '/',
component: () => import('#/List')
},
{
path: '/test2route',
component: () => import('#/List')
}]
}]
Based on your route definition, the path to Link2 would actually be http://localhost:8080/test1route/test2route, since 'test2route' is a child of 'test1route'.