Back to Course |
Vue.js 3 + Laravel 11 + Vite: SPA CRUD

Vue Route Names and Separate File

In this lesson, we will perform some route cleanup in Vue. We will introduce route naming and move the routes into a separate file.


Named Routes

So let's add a name to the routes.

resources/js/app.js:

import './bootstrap';
 
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './layouts/App.vue'
import PostsIndex from './components/Posts/Index.vue'
import PostsCreate from './components/Posts/Create.vue'
 
const routes = [
{
path: '/',
name: 'posts.index',
component: PostsIndex
},
{
path: '/posts/create',
name: 'posts.create',
component: PostsCreate
},
]
 
const router = createRouter({
history: createWebHistory(),
routes
})
 
createApp(App)
.use(router)
.mount('#app')

So how to use them by name now? In the main App layout for the links instead of hard-coding them we need to bind them to the name, like <router-link :to="{ name: 'posts.create' }">.

resources/js/layouts/App.vue:

<template>
// ...
<!-- Navigation Links -->
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<router-link to="/" active-class="border-b-2 border-indigo-400" class="inline-flex items-center px-1 pt-1 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out">
<router-link :to="{ name: 'posts.index' }" active-class="border-b-2 border-indigo-400" class="inline-flex items-center px-1 pt-1 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out">
Posts
</router-link>
<router-link to="/posts/create" active-class="border-b-2 border-indigo-400" class="inline-flex items-center px-1 pt-1 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out">
<router-link :to="{ name: 'posts.create' }" active-class="border-b-2 border-indigo-400" class="inline-flex items-center px-1 pt-1 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out">
Create Post
</router-link>
</div>
// ...
</template>

Defining routes by names gives us flexibility. If we decide to change the path we wouldn't need to change manually in every file where we used that route.


Routes in a Separate File

Now let's transform these routes into a separate file. Create a new file with the below code.

resources/js/routes/index.js:

import { createRouter, createWebHistory } from 'vue-router';
 
import PostsIndex from '@/components/Posts/Index.vue'
import PostsCreate from '@/components/Posts/Create.vue'
 
const routes = [
{
path: '/',
name: 'posts.index',
component: PostsIndex
},
{
path: '/posts/create',
name: 'posts.create',
component: PostsCreate
},
]
 
export default createRouter({
history: createWebHistory(),
routes
})

To be able to import this routes file into the main app.js instead of assigning it to a variable, we used export default.

And now we can import this routes file inside the main app.js and remove the old code for the routes.

resources/js/app.js:

import './bootstrap';
 
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './layouts/App.vue'
import PostsIndex from './components/Posts/Index.vue'
import PostsCreate from './components/Posts/Create.vue'
 
import router from './routes/index'
const routes = [
{ path: '/', component: PostsIndex },
{ path: '/posts/create', component: PostsCreate },
]
 
const router = createRouter({
history: createWebHistory(),
routes
})
 
createApp(App)
.use(router)
.mount('#app')

Now you can visit the page and it should work as expected. We didn't change anything visually, but added more order in our code for the future routes.