Skip to content

Routing

David Graham edited this page Jun 26, 2018 · 11 revisions

In this section of the tutorial we'll look at handling routing and using routes to reduce application load time.

Configure Site Root Subfolder

If you are viewing this app via the live demo on Github, you will notice the domain name and subfolder: https://vue.pizza/app. The "/app" part of the URL must be configured in a few places. You'll need to update these places with your own subfolder (or "/" if at the root of your domain name):

Router Base

Update the base of your router:

src/http/router.js

// ...

/**
* The Router instance containing all the routes for the application.
*/
const router = new Router({
  base: '/app',             // <-- update here
  mode: 'history',
  routes: routes.map(route => ({
    name: route.name,
    path: route.path,
    component: route.component,
    beforeEnter: route.isPublic ? null : guardRoute
  }))
})

Build Config AssetsPublicPath

Update your build config's assetsPublicPath:

build/config/index.js

// ...

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/app/',    // <-- update here

Install VueRouter

VueRouter was installed from the VueCli PWA template, however, if you want to install it manually you can with:

$ npm install vue-router --save-dev

Setup Routing

Router

Let's create a file that will export a new Router instance and also setup a route guard for authenticated routes:

src/http/router.js

import Vue from 'vue';
import Router from 'vue-router';
import routes from './routes';

Vue.use(Router)

/**
* Guard the route from unauthorized users.
*
* @param  {Route}    to   The route we want to access.
* @param  {Route}    from The route from which we are coming from.
* @param  {Function} next Callback for passing a route to be called next.
* @return {void}
*/
function guardRoute (to, from, next) {
  // work-around to get to the Vuex store (as of Vue 2.0)
  const auth = router.app.$options.store.state.auth

  if (!auth.isLoggedIn) {
    next({path: '/login', query: { redirect: to.fullPath }})
  } else {
    next()
  }
}

/**
* The Router instance containing all the routes for the application.
*/
const router = new Router({
  base: '/app',
  mode: 'hash',
  routes: routes.map(route => ({
    name: route.name,
    path: route.path,
    component: route.component,
    beforeEnter: route.isPublic ? null : guardRoute
  }))
})

export default router 

Routes

Now the routes:

src/http/routes.js

/**
 * Every route becomes a chunk, loaded only when used.
 * Reduces size of initial App load.
 */
const routes = [
  {
    name: 'login',
    path: '/login',
    component: () => import(/* webpackChunkName: "login" */ '@/features/login/main.vue'),
    title: 'Login',
    layout: 'NoAuthLayout',
    isPublic: true
  },
  {
    name: 'dashboard',
    path: '/',
    component: () => import(/* webpackChunkName: "dashboard" */ '@/features/dashboard/main.vue'),
    title: 'Dashboard',
    layout: 'DefaultLayout',
    isPublic: false
  },
  {
    name: 'account',
    path: '/account',
    component: () => import(/* webpackChunkName: "account" */ '@/features/account/main.vue'),
    title: 'Account',
    layout: 'DefaultLayout',
    isPublic: false
  }
]

Webpack 3 Chunk Naming

With Webpack 3 we can give names to the chunks created from the routes:

build/webpack.prod.conf.js

output: {
  path: config.build.assetsRoot,
  filename: utils.assetsPath('js/[name].[chunkhash].js'),
  chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
},

Clone this wiki locally