Skip to content

13. [vuejs-11] project: routing and navigation

Routing is what allows users to navigate between the different pages of the application.

The project directory structure is as follows:

Image

13.1. Installing dependencies

Routing in [Vue.js] requires the [vue-router] dependency:

Image

  • In [1-3], we install the [vue-router] dependency;
  • In [4-6], after installing the dependency, the [package.json] file was modified;

13.2. The routing script [router.js]

The application’s navigation rules are defined in the [router.js] file (the script name can be anything):


// imports required for routing
import Vue from 'vue'
import VueRouter from 'vue-router'

// routing plugin
Vue.use(VueRouter)

// target components for routing
import Component1 from './components/Component1.vue'
import Component2 from './components/Component2.vue'
import Component3 from './components/Component3.vue'


// the application's routes
const routes = [
  // home
  { path: '/', name: 'home', component: Component1 },
  // Component1
  {
    path: '/view1', name: 'view1', component: Component1
  },
  {
    // Component2
    path: '/view2', name: 'view2', component: Component2
  },
  // Component3
  {
    path: '/view3', name: 'view3', component: Component3
  },
]

// the router
const router = new VueRouter({
  routes,
  mode: 'history',
})

// export the router
export default router

Comments

  • The [router.js] script will define the routing rules for our application;
  • lines 1–6: Enabling the [vue-router] plugin required for routing. This requires importing the [Vue] class/function (line 2) and the routing plugin (line 3). This plugin was installed with the [router] dependency we just installed;
  • lines 8–11: import the target views for routing;
  • lines 15–21: definition of the routes array. Each element of this array is an object with the following properties:
    • [path]: the view’s URL, the one we want to see displayed in the browser’s [URL] field. You’re free to enter whatever you want;
    • [name]: the route name. Here, too, you can enter whatever you want;
    • [component]: the component that displays the view. This must be an existing component;

So here we have four routes: [/], /view1, /view2, /view3.

  • Lines 33–36: The router is an instance of the [VueRouter] class imported on line 3. The [VueRouter] constructor is used here with two parameters:
    • the application’s routes;
    • a mode for writing URLs in the browser: the default mode [hash] writes URLs in the form [localhost:8080/#/view1] (# is the hash). The [history] mode removes the # [localhost:8080/view1];
  • Line 39: Export the router;

13.3. The main script [main.js]

The main script [main.js] is as follows:


// imports
import Vue from 'vue'
import App from './App.vue'

// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// Bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// router
import myRouter from './router'

// configuration
Vue.config.productionTip = false

// project instantiation [App]
new Vue({
  name: "app",
  // main view
  render: h => h(App),
  // router
  router: myRouter,
}).$mount('#app')

Comments

  • line 14: we import the router exported by the [router.js] script;
  • line 25: this router is passed as a parameter to the constructor of the [View] class, which will display the main view [App], associated with the view's [router] property;

13.4. The main view [App]

The code for the main view is as follows:


<template>
  <div class="container">
    <b-card>
      <!-- a message -->
      <b-alert show variant="success" align="center">
        <h4>[vuejs-11]: Routing and Navigation</h4>
      </b-alert>
      <!-- the current routing view -->
      <router-view />
    </b-card>
  </div>
</template>

<script>
  export default {
    name: "app"
  };
</script>

Comments

  • line 9: displays the current view in the router. The <router-view> tag is only recognized if the view's [router] property has been initialized;

13.5. View Layout

View layout is handled by the following [Layout] component:


<template>
  <!-- line -->
  <div>
    <b-row>
      <!-- three-column section -->
      <b-col cols="2" v-if="left">
        <slot name="left" />
      </b-col>
      <!-- nine-column area -->
      <b-col cols="10" v-if="right">
        <slot name="right" />
      </b-col>
    </b-row>
  </div>
</template>

<script>
  export default {
    // settings
    props: {
      left: {
        type: Boolean
      },
      right: {
        type: Boolean
      }
    }
  };
</script>

We have already used and explained this layout in the [vuejs-06] project in section [vuejs-06].

13.6. The Navigation Component

The [Navigation] component provides a navigation menu to the user:

Image

The component that generates block [1] is as follows:


<template>
  <!-- Bootstrap menu with three options -->
  <b-nav vertical>
    <b-nav-item to="/vue1" exact exact-active-class="active">View 1</b-nav-item>
    <b-nav-item to="/view2" exact exact-active-class="active">View 2</b-nav-item>
    <b-nav-item to="/view3" exact exact-active-class="active">View 3</b-nav-item>
  </b-nav>
</template>
  • This code generates the first of three navigation links;
  • the [to] attribute of the <b-nav-item> tags must match one of the [path] properties of the application router's routes;

13.7. The Views

View #1 is as follows:

Image

Areas [3-4] are generated by the following [Component1] component:


<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message-->
    <b-alert show variant="primary" slot="right">View 1</b-alert>
  </Layout>
</template>

<script>
  import Navigation from './Navigation';
  import Layout from './Layout';

  export default {
    name: "component1",
    // components used
    components: {
      Layout, Navigation
    }
  };
</script>

Comments

  • line 2: view #1 uses the [Layout] component's layout, which consists of two slots named [left] and [right];
  • line 4: the navigation menu is placed in the left slot. This is area [3] shown above;
  • line 6: a message is placed in the right slot. This is area [4] shown above;

Views 2 and 3 are similar.

View #2 displayed by the [Component2] component:


<!-- view #2 -->
<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message -->
    <b-alert show variant="secondary" slot="right">View 2</b-alert>
  </Layout>
</template>

<script>
  import Navigation from './Navigation';
  import Layout from './Layout';

  export default {
    name: "component2",
    // view components
    components: {
      Layout, Navigation
    }
  };
</script>

View #3 displayed by the [Component3] component:


<!-- view #3 -->
<template>
  <Layout :left="true" :right="true">
    <!-- navigation -->
    <Navigation slot="left" />
    <!-- message -->
    <b-alert show variant="info" slot="right">View 3</b-alert>
  </Layout>
</template>

<script>
  import Navigation from "./Navigation";
  import Layout from "./Layout";

  export default {
    name: "component3",
    // view components
    components: {
      Layout,
      Navigation
    }
  };
</script>

13.8. Running the project

Image

Upon execution, the following view is displayed:

Image

  • in [1], the URL is [http://localhost:8080]. The following routing rule was then executed:

{ path: '/', name: 'home', component: Component1 }

Therefore, the [Component1] component was displayed. It displays view #1 [2]. Now let’s click on the [View 1] link, whose code is as follows:


<b-nav-item to="/view1" exact exact-active-class="active">View 1</b-nav-item>

The display now looks like this:

  • In [3], the following routing rule was executed:

path: '/view1', name: 'view1', component: Component1

So once again, the [Component1] component was displayed, and thus View 1 [4]. Now let’s click on the [View 2] link, whose code is as follows:


<b-nav-item to="/view2" exact exact-active-class="active">View 2</b-nav-item>

The new view is then as follows:

Image

  • in [5], the following routing rule was executed:

path: '/view2', name: 'view2', component: Component2

Therefore, the [Component2] component was displayed, which is View 2. If we now click on the [View 3] link, whose code is as follows:


<b-nav-item to="/view3" exact exact-active-class="active">View 3</b-nav-item>

We get the following new view:

Image

  • in [6], the following routing rule was executed:

path: '/view3', name: 'view3', component: Component3

Therefore, the [Component3] component was displayed, i.e., view #3 [8].