1. Dynamic routing

Use in pages

router/index.js

const routes = [
  {
    path: '/'.name: 'Index'.component: Index
  },
  {
    path: '/detail/:id'.name: 'Detail'.// Enable props to pass the parameters in the URL to the component
    props: true.// Use this parameter
    // 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/Detail.vue')
  }
]
view/Detail.vue

<template>
  <div>This is the Detail page<! -- Method 1: Obtain data based on the current routing rules -->{{$route.params.id}}<! -- Method 2: Enable the props parameter for routing rules (recommended) -->Obtain this parameter by enabling props: {{id}}</div>
</template>

<script>
export default {
  name: 'Detail'.// Set the route parameters to props
  props: ['id']}</script>
Copy the code

Two, set routine by

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Layout from '.. /components/Layout.vue'
import Login from '.. /views/Login.vue'
import Index from '.. /views/Index.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/login'.name: 'login'.component: Login
  },
  // Set set by
  {
    path: '/'.component: Layout,
    children: [{path: ' '.name: 'index'.component: Index
      },
      {
        path: 'detail/:id'.name: 'detail'.props: true.component: () = > import('@/views/Detail.vue')}]}]const router = new VueRouter({
  routes
})

export default router

### // components/Layout.vue

<template>
  <div>
    <div>
      <img width='80px' src='@/assets/logo.png'>
    </div>
    <div>
      <router-view></router-view>
    </div>
    <div>
      Footer
    </div>
  </div>
</template>
Copy the code

Three, programmatic navigation

1. this.$router.replace(‘/login’)

this.$router.replace('/login') Replace has no historyCopy the code

2. this.$router.push({ name: ‘Detail’, params: { id: 1 } })

 this$router. Push ('/') push with historyCopy the code

3. this.$router.go(-2)

Go () go to that pageCopy the code

Hash mode and History mode

1. The difference of expression form

  • Hash mode: http://localhost/#/detail? id=1234
  • The History mode: http://localhost/detail/1234

2. Differences in principles

  • The Hash pattern is based on anchor points, as well as onHashChange events.
  • The History mode is based on the HTML5 History API history.pushState ().

3. Use of the History mode

  • History requires server support

  • In a single-page application, if the server does not have an address such as www.test.com/login, the server returns that the page cannot be found

  • Return the index. HTML of the single-page application on the server except for static resources.

  • Server Configuration

    Node.js server configuration

    Const History = require(‘connect-history-api-fallback’) // Import express const express = require(‘express’)

    Const app = express() // Key: register middleware that processes history mode app.use(history()) // Middleware that processes static resources, site root directory.. /web app.use(express.static(path.join(__dirname, ‘.. /web’)))

    App.listen (3000, () => {console.log(‘ server enabled, port: 3000’)}) Nginx server configuration

    Start the start nginx

    Restart nginx-s reload

    -s stop nginx.conf

 http: {
  	server: { location / { root html; index index.html index.htm; Try_files $uri $uri/ /index.html; }}}Copy the code

4. The Hash pattern

  • Whatever follows the # in the URL is the path address
  • Listen for hashChange events
  • Find the corresponding component to re-render according to the current routing address

5. The History mode

  • Change the address bar with the history.pushState () method (no request is sent to the server, but this URL is recorded in History)
  • Listen for popstate events
  • Find the corresponding component to re-render according to the current routing address

Five, simulation implementation

Analysis of the code

  • Options Records the routing rules transmitted
  • RouteMap Maps routing addresses to components, and future routing rules are resolved into a routeMap
  • Data is a reactive object containing the current routing address
  • + is a public method _ is a static method

Install is vUE’s plug-in mechanism

The build version of Vue

  • Runtime version: No support for template templates, and use the render function when packaging
Vue.component('router-link', {
      props: {
        to: String
      },
      render (h) {
        return h('a', {
          attrs: {
            href: this.to
          },
          
        }, [this.$slots.default])
      },
      // template: '<a href="to"><slot></slot></a>'
    })
Copy the code
  • Full version: includes the runtime and compiler, about 10K larger than the runtime version, and converts the template to render as the program runs

Add a file to the project root directory: vue.config.js

Module. Exports = {// complete Vue (with compiler) runtimeCompiler: true}

Handwritten vuerouter, just simulation, not source code

let _Vue = null

export default class VueRouter {
  static install (Vue) {
    // 1. Check whether the current plug-in is installed
    if (VueRouter.install.installed) return
    VueRouter.install.installed = true
    // 2. Record the Vue constructor as a global variable
    _Vue = Vue
    // 3. Inject the router object passed in when the Vue instance is created into the Vue instance
    / / with
    _Vue.mixin({
      beforeCreate () {
        if (this.$options.router) {
          _Vue.prototype.$router = this.$options.router
          this.$options.router.init()
        }
      }
    })
  }

  constructor (options) {
    this.options = options
    this.routeMap = {}
    // _vue.Observable creates a responsive object
    this.data = _Vue.observable({
      current: '/'
    })
  }

  init () {
    this.createRoutMap()
    this.initComponents(_Vue)
    this.initEvent()
  }

  createRoutMap () {
    // Iterate over all the routing rules, parse the routing rules into key-value pairs and store them in the routeMap
    this.options.routes.forEach(route= > {
      this.routeMap[route.path] = route.component
    })
  }

  initComponents (Vue) {
    Vue.component('routeLink', {
      props: {
        to: String
      },
      render (h) {
        return h('a', {
          attrs: {
            href: this.to
          },
          / / event
          on: {
            click: this.clickHandler
          }
        }, [this.$slots.default])
      },
      methods: {
        clickHandler (e) {
          history.pushState({}, ' '.this.to)
          this.$router.data.current = this.to
          e.preventDefault()
        }
      }
      // template: '<a href="to"><slot></slot></a>'
    })
    const self = this
    Vue.component('routerView', {
      render (h) {
        const component = self.routeMap[self.data.current]
        return h(component)
      }
    })
  }

  initEvent () {
    window.addEventListener('popstate'.() = > {
      this.data.current = window.location.pathname
    })
  }
}
Copy the code