Vue router learning notes

Vue-Router

brief introduction

Routing is the activity of transmitting information from the source address to the destination address through the interconnected network

Back end Routing: the back end processes the mapping relationship between URL s and pages

With the emergence of the front and rear end separation stage, the single page rich application stage will be reached:

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

When we enter a website, we will download all its resources html+css+js. At this time, we use front-end routing, such as url: own domain name / home url: own domain name / about

At this time, we extract the required resources from all resources, which are components in our vue

In essence, front-end routing is the mapping relationship between url and components. Extracting resources is to extract mapped resources from all resources and render them

Preparation stage

hash of URL

In essence, it is the parameter splicing of the web address, which will not refresh the page and request resources

Can be in the console

location.hash = "home"

pushState in H5

Can be in the console

history.pushState({},'','home');

Here we compare similar stack structures

history.pushState({},'','me');

At the top of the current stack is the me page

Enter history Back() we will return to the home page

replaceState in H5

history.replaceState({},'','home')

history.replaceState({},'','about')

We don't have a back button at this time

go in H5

This is to jump to a stack

history.pushState({},'','home');

history.pushState({},'','me');

history.pushState({},'','about');

history.pushState({},'','test');

history.pushState({},'','demo');

At this time, we enter in the demo page

history.go(-3)

At this time, the stack jumps out of three, and we reach the me page

history.go(2)

At this time, we push two into the stack to reach the test page

So history Back() is equivalent to history go(-1),history. Forward () is equivalent to go(1)

Cognitive configuration

At present, the three popular front-end frameworks have their own routing implementation:

  • ngRouter of Angular
  • ReactRouter of React
  • Vue router of Vue

install

①npm install vue-router --save

② Use it in a modular project (because it is a plug-in, you can install the routing function through Vue.use())

  1. Import the routing object and call Vue use(VueRouter)
  2. Create a routing instance and pass in the routing mapping configuration
  3. Mount the created routing instance in the Vue instance

Build routing framework

The following is the index in our router folder JS routing related configuration

//Configure routing information

import Vue from 'vue'
import VueRouter from 'vue-router' 
import Home from '../views/Home.vue'

// 1. Call vue Use to install the vue plug-in, provided vue is introduced (line 3)
Vue.use(VueRouter)


// This is where we configure the url mapping relationship
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]
// 2. Create vueroter object
const router = new VueRouter({
  routes
})

// 3. Pass the router object into the Vue instance
export default router

Configure the mapping relationship of routes

  1. Create routing component
  2. Configure route mapping: component and path mapping relationship

Index. In the router folder Configuration relationship in JS file

//Import components
import Home from "../components/Home"
import About from "../components/About"

const routes = [
    {
        path:'/home',
        component:Home
    },
    {
        path:'/about',
        component:About
    }
]
  1. Using routing: through and

On app In Vue file

<template>
  <div id="app">
       <router-view></router-view>
    <router-link to="/home">home page</router-link>
    <router-link to="/about">about</router-link>
 
  </div>
</template>

Default path for routing

  • That is, as soon as you open the web page, you go to a component

Here, we also need to define it in the router,

const routes = [
	{
		path:'/',
		// Redirect redirect
		redirect:'/home'
	}
    {
        path:'/home',
        component:Home
    },
    {
        path:'/about',
        component:About
    }
]

Modify hash mode

"#" will appear when we change the path, as long as we change the mode from hash to history

Set when creating the vueroouter object

// 2. Create vueroter object
const router = new VueRouter({
  routes,
  mode:'history'
})

use

<router - link>

  • tag attribute

By default, our tag will be rendered as a tag, but we can use its tag attribute to change its tag

tag="button" this will become a button

 <router-link to="/home" tag="button">home page</router-link>
  • replace

Sometimes we don't want the back and forward buttons to appear, so we use the replace tab

  • Active class attribute

Modify the default name when clicked, which is very convenient when used in combination with CSS

active-class = "actived"

<router-link to="/home" tag="button" active-class="actived">home page</router-link>
<router-link to="/home" tag="button" active-class="actived">about</router-link>

Sometimes we don't want to write active class on a large number of labels, so we can use index JS to modify the default name of the clicked component

const router = new VueRouter({
  routes,
  mode:'history',
  linkActiveClass:'actived'
})

Code implementation routing

<template>
  <div id="app">
       <router-view></router-view>
    <!-- <router-link to="/home" tag="button" replace>home page</router-link>
    <router-link to="/about" tag="li" replace>about</router-link> -->
  <button @click="homeBtn">home page</button>
 <button @click="aboutBtn">about</button>
  </div>
</template>

<script>
export default{
    name:'App',
    methods: {
      homeBtn(){
       //The router here is index Variable name const router in JS file
        //this.$router.push('/home') has a return button
        this.$router.replace('/home').catch(err=>[])
        console.log("home")
      },
        aboutBtn(){
        this.$router.replace('/about').catch(err=>[])
        console.log("about")
      },
    }
  }
</script>

Dynamic routing

Sometimes we need to load the user interface, and we need to jump according to the user id

First, we need the index Configuring users in JS
  • Variable names are specified
 {
    path:'/user/:userId',
    component:User
  },

Data in data

data(){
      return{
      userId:"Joseph"
      }

In the template, we use v-bind to use variables

<template>
  <div id="app">
  

    <router-link v-bind:to="/user/+userId"  tag="button" replace>my</router-link>
         <router-view></router-view>

  </div>
</template>

We get data from the parent component and display it in the child component user

User. We show it in the Vue file

<template>
  <div>
      <h2>I'm a user</h2>
      <p>I am the user's relevant information</p>
      <h3>{{userId}}</h3>
      <h3>{{$route.params.userId}}</h3>
  </div>
</template>

<script>
export default {
    name:"User",
    computed: {
        userId(){
            // The route obtained here is the route in the active state in the routing table
            // Active status refers to which component you are currently displaying (using)
                return this.$route.params.userId
            }
    }
}

</script>

$route is different from $route

The former is for us to obtain our VueRouter, and the latter is for us to obtain the route in the current active state

Lazy loading of routes

Because of our bundle JS resources are too large (because various packaging underlying code transformations are in it). We don't want to open and load resources for a long time, that is, there is a page blank period

  • Therefore, if we can divide the components corresponding to different routes into different code blocks, and then load the corresponding components when the routes are accessed, it will be more efficient

Essence: package different routes into different JS files

We just need to write in index JS can modify the writing method of the routing table

const routes = [

    {
        path:'/',
        redirect: '/home'
    },
    {
        path:'/user/:userId',
        //neographism
        component:()=>import('../components/User')
    },
    {
        path:'/home',
        component:()=>import('../components/Home')
    },
    {
        path:'/about',
        component:()=>import('../components/About')
    }
]

Or we define the variable as an imported statement at the beginning

const Home =  ()=> import('../components/Home');
const About = ()=> import('../components/About');
const User = ()=> import('../components/User');

const routes = [
  {
    path:'/',
    redirect: '/home'
  },
  {
    path:'/user/:userId',
    component:User
  },
 {
  path:'/home',
  component:Home
 },
 {
  path:'/about',
  component:About
 }
]

Nested use of routes

  • For example, we can access some content in home/news and home/message
  • One path maps to one component, and accessing these two paths will render two components respectively

There are two steps to implement nested Routing:

  1. Create corresponding sub components and configure corresponding sub routes in route mapping

Here we have created two vue components, HomeNews and HomeMessage, which are introduced as follows

const HomeNews = ()=> import('../components/HomeNews');
const HomeMessage = ()=> import('../components/HomeMessage');
//We add the child of Home in the routing table
{
  path:'/home',
  component:Home,
  childern:[
    {
      path:'news',
      component:HomeNews
    },
    {
      path:'message',
      component:HomeMessage
    }
  ]
 }

Note: the sub path here does not need to be preceded by "/" because it is a relative path

  1. Use labels inside components

Here we need to add tags in the template of the home component

Home. Templates in Vue files

<template>
    <div>
        <h2>I'm the home page</h2>
        <p>
            I am the content of the home page
        </p>
        <router-link to="/home/news" tag="button">Journalism</router-link>
        <router-link to="/home/message" tag="button">news</router-link>
        <router-view></router-view>
    </div>
</template>

Note: Here we use the absolute path to

Similarly, we give it a default path to the page

 children:[
    {
      path:'',
      redirect: 'news'

    },
    ...
   ]

Parameter transfer

  • In dynamic routing, we use $route params. Userid, which is the way in which parameters are always passed

There are two main types of parameters we pass: params and quert

  • Type of params

    • Configure routing format: / router/:id
    • Transfer method: follow the path with the corresponding value (string splicing of the to attribute in the router link tag)
    • Paths formed after transfer: / router / 123, / router / ABC
  • query

    • Configure routing format: / router, that is, normal configuration
    • Transfer method: the key of query is used as the transfer method in the object
    • Path formed after transfer: / router?id=123, /router?id=abc
     <router-link :to="{path:'/profile',query:{name:userId,age:19,height:1.70}}" tag="button" replace>archives</router-link>
    

http://localhost:8080/profile?name=Joseph&age=19&height=1.7

URL: protocol: / / host: port / path? Query # fragment

​ scheme://host:port/path?query#fragment

So how do we get information from query?

this.$route.query, we can get this object

<template>
  <div>
      <h2>
          I am Profile
      </h2>
      <span>
          {{this.$route.query}}
      </span>
  </div>
</template>

<script>
export default {
    name:'Profile'
}
</script>

Navigation guard

  • Sometimes we want to listen to the jump of components. According to the previous method, we will use the life cycle, created, mounted and updated, and the callback function executed when it is created, mounted and updated
  • Current requirements: click component, document The title will change. We can call back in the life cycle function, but this will be written in each component

So we use our global navigation guard

First, we need to define metadata (data describing data) meta for each route

const routes = [

  {
    path:'/',
    redirect: '/home',
    meta:{
      title:'home page'
    }
  },
  {
    path:'/user/:userId',
    component:User,
    meta:{
      title:'user'
    }
  },
  {
    path:'/home',
    component:Home,
    children:[
      {
        path:'',
        redirect: 'news'

      },
      {
        path:'news',
        component:HomeNews
      },
      {
        path:'message',
        component:HomeMessage
      }
    ],
    meta:{
      title:'home page'
    }
  },
  {
    path:'/about',
    component:About,
    meta:{
      title:'about'
    }
  },
  {
    path:'/profile',
    component:Profile,
    meta:{
      title:'User profile'
    }
  }
]

Then we use the navigation guard

//This is the vueroter object
const router = new VueRouter({
  routes,
  mode:'history',
  linkActiveClass:'actived'
})

//Front hook and guard (need to actively call next() function)
router.beforeEach((to,from,next)=>{
    
   	//Code to implement requirements
    document.title = to.meta.title
    
    //This next() must be written. If it is not written, all components in the router cannot jump
    //After calling this method, you can enter the next hook
    next();
    
    //Sometimes we don't want users to jump directly, such as login and registration
    //We can add some conditional judgment, and then jump to the corresponding path
    //For example, if(){next('/login')}
    
})

be careful

When we go in, the first page title we get is undefined, which is caused by the nesting of routes

When we print to, we find that there is a matched array. The path of matcher[0] is' / home ', and the path of matcher[1] is' / home/news', so we need to change the document title = to. matched[0]. meta. title

Rear hook, guard

router.afterEach((to,from)=>{

})

All of the above are global guards. In addition, there are

  • Route exclusive guard
const routes = [

  {
    path:'/user/:userId',
    component:User,
    meta:{
      title:'user'
    },
    beforeEnter:(to,from,next)=>{
    	...
    	next()
    }
  },
 	...
 ]
  • Guard in component (document use)

keep-alive

  • Note: when we switch components, nothing remains, so every time we switch components, we will call the create function in their life cycle function, that is, every time we create components.

    • Therefore, there is a destroyed () periodic function inside our component
  • Keep alive is a built-in component of Vue, which can keep the contained components in the state or avoid re rendering

  • Router view is also a component (defined at the time of new Vue router). If it is directly wrapped in keep alive, all view components matching the path will be cached

         <keep-alive>
            <router-view></router-view>
         </keep-alive>

Now demand: when you enter the home page, the default is to display the news. First click the home page message, then click the user, and then when you return to the home page, you will see the home page message

This can be solved by using the navigation guard and active state function we mentioned earlier

At home In Vue

<template>
    <div>
        <h2>I'm the home page</h2>
        <p>
            I am the content of the home page
        </p>
        <router-link to="/home/news" tag="button">Journalism</router-link>
        <router-link to="/home/message" tag="button">news</router-link>
        <router-view></router-view>
    </div>
</template>

<script>
export default {
        name:"Home",
        data(){
            return{
                path:'/home/news'
            }
        },
        created () {
            console.log("created")
        },
        destroyed () {
            console.log("destory")
        },

    //The following two functions are valid in the case of keep alive
        activated () {
          console.log("HOME The component is active");
          this.$router.push(this.path).catch(err=>{})
            //Here The reason for catch is to avoid repeated submission of routing console errors through / home/news
        },
        deactivated () {
            console.log("HOME Component resting in cache")
        },

        beforeRouteLeave(to,from,next){
            console.log(this.$route.path);
            this.path = this.$route.path

            next();
        }
    }
</script>

Note: sometimes we don't want all components in the app to be cached. For example, we want to re create some files. At this time, we have two very important properties

  • include - string or regular expression that takes care of matching components will be cached

  • exclude - string or regular expression. Any matching components will not be cached

  • The string inside is the name attribute of each vue component when exporting

         <keep-alive exclude="Profile,User">
            <router-view></router-view>
         </keep-alive>

Keywords: Vue vue-router

Added by insight on Thu, 13 Jan 2022 23:57:36 +0200