1. What is a route

The first thing we need to figure out is what is a route

From Wikipedia: The act of transferring information from source to destination over an interconnected network.

In other words, when we enter different urls in the browser’s address bar and the browser shows us different pages, it is a routing process.

In fact, routing includes an important concept called routing table: the essence of routing table is a mapping table, which determines the direction of our data.

Routing is also divided into two phases, and each phase has its own way of implementing routing. The two periods are back-end routing and front-end routing respectively.

1.1 Back-end Routes

In the early days of web development, the front and back ends were developed on a server, which is often referred to as server-side rendering.

When the user sends a request to the server, the server returns a different HTML page based on the URL to the front end. When we need to request different path content in the page, we hand it over to the server for processing, the server renders the entire page, and returns the page to the client.

This operation is called back-end routing.

Advantages: no need to load any SEPARATE JS and CSS, can be directly presented to the browser, which is also conducive to SEO optimization.

Disadvantages: too chaotic, front and back end division of labor is not clear, server pressure

1.2 Front-end Routing

For front-end routes, the route mapping function usually does some DOM show and hide operations. In this way, different page components are displayed when accessing different paths. That is how we can change the URL but not refresh the page as a whole.

Front-end routing started with Ajax, and with Ajax, the user interaction didn’t have to refresh the page every time, resulting in a vastly improved experience. With the development of technology, simple asynchronous is no longer enough, so a more advanced experience of asynchronous emerged — SPA (Single page rich application)

In fact, the most important feature of SPA is to add a layer of front-end routing on the basis of the separation of front and back ends. That is, the front end maintains a set of rules

Implementation of front-end routing:

There are two ways to implement this, one is hash, and the other is history using BOM in HTML5.

You can change the URL in both ways without refreshing the page.

Hash:

Early implementations of front-end routing were based on location.hash. The implementation principle is simple: the value of location.hash is the content after the # in the URL.

Example:

location.hash='bar'
Copy the code

The History API:

The main methods are pushState() and replaceState(), which push the value of our route onto the stack and can then be accessed back and forth using go, etc., but the latter can only replace the current route and has no history.

history.pushState({},' '.'a')
history.pushState({},' '.'b')
history.pushState({},' '.'c')
history.go(-2)//a
Copy the code

2. Vue-router is used basically

Vue-router is the official routing plug-in of VUE. It is deeply integrated with vue.js and suitable for building single-page applications. Routing is used to set access paths and map paths to components.

In a vue-Router single-page application, a change in the path of the page is a component switch.

Setup (with scaffolding we can directly choose to initialize these operations) :

npm install vue-router --save
Copy the code

2.1 Building a routing Framework:

  1. Step 1: Import the routing object and call vue.use (VueRouter) to download the plug-in
  2. Step 2: Create a route instance and pass in the route mapping configuration
  3. Step 3: Mount the created routing instance in the Vue instance

The router code:

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
  routes: []})Copy the code

Mount instance code:

import router from './router'
new Vue({
  el: '#app',
  router,
  render: h= > h(App)
})
Copy the code

2.2 Configuring Route Mapping

  1. Step 1: Create the routing component
  2. Step 2: Configure route mapping: Component and path mapping
  3. Step 3: Use routing: Pass and

Configuring routing components:

 routes: [
    {
      path: '/hello'.component: HelloWorld
    },
    {
      path:'/home'.component:home
    },
    {
      path:'/about'.component:about
    }
  ]
Copy the code

Using routing:

<template>
  <div id="app">
    <router-link to="hello">hello</router-link>
    <router-link to="home">home</router-link>
    <router-link to="about">about</router-link>
    <router-view></router-view>
  </div>
</template>
Copy the code

Note:

  1. : This tag is a component already built into vue-Router and will be rendered as an A tag
  2. : This TAB dynamically renders different components based on the current path.
  3. The rest of the page, such as the title/navigation at the top, or some copyright information at the bottom, is at the same level.

Other operations on the router-link tag:

The router-link tag can also specify a tag that will not pass, which can be set using the tag attribute.

The router-link tag’s default jump behavior is push, which can be changed to replace by specifying the replace attribute directly.

 <router-link to="about" tag="button" replace="">about</router-link>
Copy the code

2.3 Setting the Default Route

The default route is the route displayed when we first enter the page. This requires us to configure the mapping relationship in the Router. Just add a configuration

  {
      path:'/'.redirect:'/home'
  },
Copy the code

2.4 Changing the Front-end Routing Mode

By default, vue-router uses hash for routing. As mentioned above, we have two ways of routing. We can also change the route mode to history mode by using the following code:

Simply add the mode parameter where the Router instance is created

export default new Router({
  routes: [].mode:'history'
})
Copy the code

2.6 Using codes to Redirect routes

If we don’t want to use the router-link tag during development, we can define a tag and add our own logic to implement router-link operations.

We use $Router, a global attribute provided by the Router plug-in. This property can directly specify the jump to the specified route via the push method and the replace method.

Example:

aboutclick() {
      this.$router.push("/about");
},
Copy the code

Note: When jumping this way, there was no problem until vue-Router 3.1, but later the $router.push() ‘method was changed to Promise. So if there were no callback function, the error message would be passed to global routing error handling, and thus the following error would be reported.

[NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated"}]

There are two ways to solve this problem:

  1. Switch version (= not said)
  2. Disable global route error handling printing, which is also the solution given by vue-Router developers: add the following code where VueRouter is defined
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err= > err)
}
Copy the code

2.7 Dynamic Routing

If you’ve studied NodeJS or learned something about the back end, you’ll see that dynamic routing here is very similar. It doesn’t require us to pass in a fixed value. This scenario might appear in the category display, and when the user clicks on the corresponding entry our path might be: /product/man or /product/women.

In this way, in addition to our fixed product, we also followed the product segmentation, and then displayed different data through these. We also call this operation dynamic routing.

This requires us to set up the mapping like this:

 {
      path:'/product/:classify'.component:person
 }
Copy the code

Then add our dynamic content when using:

 <router-link :to="'/product/' + classify">home</router-link>//classify indicates dynamic dataCopy the code

In fact, this can achieve dynamic routing. If we also want to output our classify variable to the component, we can use the $Route attribute, which retrieves the currently active routes.

 <p>{{ $route.params.userid }}</p>
Copy the code

2.8 Lazy route loading

The official explanation for lazy loading of routes is:

JavaScript packages can become very large when packaged to build applications, affecting page loads. It would be much more efficient if we could split the components corresponding to different routes into different code blocks and then load the components only when the routes are accessed.

Actually means that we each routing corresponding is a show user page, but according to the normal operating these pages may end webpack packaged as a bundle of js file, which caused the page is very huge, where the request may take some time, bad to cause the user experience. So we can solve this problem by routing lazy loading. This means that different routing pages are packaged into different JS files, which eliminates the server’s time consuming problem.

When we did not use lazy loading, the packaged Vue project would generate three files, one is all the business code of the APP, one is the code of the organization and management module relationship, and one is the code of the third party introduced by the project.

Then let’s look at the way lazy loading is implemented: there are three ways to combine asynchronous components, AMD way, es6 modular way

In ES6, we can write a much simpler way to organize code splitting between Vue asynchronous components and Webpack. So we did it the simplest way:

 component: () = > import('.. /components/about.vue') 
Copy the code

Example:

 routes: [
    {
      path: '/'.redirect: '/home'
    },
    {
      path: '/hello'.component: () = >import('.. /components/HelloWorld.vue')}, {path: '/home'.component: () = > import('.. /components/home.vue')}, {path: '/about'.component: () = > import('.. /components/about.vue')}, {path: '/person/:userid'.component: () = > import('.. /components/person.vue')},Copy the code

The final result of this packaging:

We found that each routing interface has a JS file, which allows us to load on demand and takes the strain off the server

3. Vue-router nested routine

Why nesting when we need to nest different interfaces in our routing component, such as our tabbed switching operation is the best use scenario

Our general operation process is as follows:

  1. Define our child routing components first
  2. Use the children attribute to define child routes in the parent route in the routing mapping table
  3. Use child routes in parent route appearances (normal use)

Look at a chestnut:

Our requirement here is to nest two components, home Max and Homenews, in the home route, and then access their contents via the home/ Home Max and home/ Homenews respectively

Define child routing implementations in the mapping table:

 {
      path: '/home'.component: () = > import('.. /components/home.vue'),
      children: [// Set the default route
        {
          path:' '.redirect:'homemessage'
        },
        {
          path: 'homemessage'.component: () = > import('.. /components/homemessage.vue'),}, {path: 'homenews'.component: () = > import('.. /components/homenews.vue'),}},Copy the code

Here we use lazy loading to import components. Note that the child path cannot be preceded by a ‘/’.

Used in parent routes:

<router-link to="/home/homemessage">The message</router-link>
<router-link to="/home/homenews">news</router-link>
<router-view></router-view> 
Copy the code

4. Transmit vue-router parameters

4.1 Two ways of parameter passing

There are basically two ways of dealing with routing parameters

The first is to use the string concatenation we talked about in dynamic routing to pass parameters from the jump page, and then use $route.params. Parameter name to accept

The second is the one we will now use in the form of query.

First, we can dynamically bind an object to the tag and pass it a Path and a Query, whose contents are the contents of the data we want to pass in (as shown in the following example) :

  <router-link
      :to="{path: '/ about', the query: {id: '001', name: 'zhang' sex: 'male'},}"
      >about</router-link
    >
Copy the code

The next step is to use $route.query to receive its arguments

<p>{{ $route.query}}</p>
<p>{{ $route.query.name}}</p>.Copy the code

This is how we pass router species parameters.


r o u t e and The route and
Router:

Router is an instance of VueRouter. If you want to navigate to different urls, you use router as instance VueRouter. If you want to navigate to different urls, you use router.push

$route indicates the current router jump object, which can obtain name, path, query, and params

5. Vue-router navigation guard

The role of the navigational guard is to monitor our current routing status.

We can imagine a scenario where we want the title to refresh in real time when switching the routing interface on a SPA page.

The first thing THAT came to my mind was to use the life cycle function of each route to convert the title using document.title when I first started the CREATE component.

But if this is a little too low and cumbersome, use our front navigator beforeEach.

This is a method on the Router instance, and the argument is a function that takes three arguments. To, from, next. To and from are both router types, so we can manipulate them to perform operations on our router.

export type NavigationGuard<V extends Vue = Vue> = (
  to: Route,
  from: Route,
  next: NavigationGuardNext<V>
) = > any
Copy the code

So for our above requirements, we can do as follows:

router.beforeEach((to,from,next) = > {
  next();
  console.log(to);
  document.title=to.matched[0].meta.title
})
Copy the code

Meta Meta data related to route source information needs to be set in the router mapping table.

The data returned by to is as follows:

Note that we had better use the matched array to set up the information, because this is our example of a route and all the nested routes in it. If you are sure that your router does not have nested routers, you can use the outer mate attribute to set the router.

** Add-on: ** In addition to the front navigational guard we actually have rear navigational guard, route navigational guard, component navigational guard, etc. We can use different guards in different scenarios.

6. Use keep-alive to cache the routing interface

Keep-alive is often used to cache components for performance savings.

Of course, keep-Alive can also cache our routes. Our routing interface is actually a component, and each component is an instance of vUE, and vUE instances follow the declaration cycle of VUE, so when we cut the current routing interface, our current component will also be destroyed. When we re-enter, we will create our component from create.

So there is an obvious need. After we perform some operations on the ROUTING interface of A, we will enter page B. When the operations on page B are finished, we want to go back to page A and continue to do what we did before. If we do not use keep-alive, we will find that we will not meet the above requirements.

Of course, different businesses have different requirements, and some require me to rebuild the DOM when I enter.

So let’s look at usage:

    <keep-alive>
      <router-view></router-view>
    </keep-alive>
Copy the code

All we need to do is wrap a keep-alive tag on top of the router-view to achieve the effect of caching.

There are also two hook functions in keep-alive, deactivated and destroyed, that are similar to the declaration of periodic functions.

Called when the component is active and inactive, respectively. So we can use the DeActivated function to do things that we need to do as soon as we enter the interface.

There is also the use of includ and exclude, specified by the component’s name attribute, respectively:

<keep-alive include="home,about">
      <router-view></router-view>
</keep-alive>
<keep-alive exclude="hello">
      <router-view></router-view>
</keep-alive>
Copy the code