Vue-router is enough to understand these in actual combat

1. Installation

1.1. Add dependency

npm install vue-router

1.2. Introduced in the project

Take the latest vue-cli3 architecture as an example, add it to main.js

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

More generally, there is generally a dedicated routing js file, such as router.js

Only router.js is introduced in main.js. And add the above quoted part in router.js. In the future, the relevant routing configuration is configured in router.js.

The directory organization of each js file mentioned above is as follows:

src

------ main.js

------ router

------------ router.js

 

1.3. Examples

First paste some examples of actual combat to understand intuitive usage

main.js

import 'babel-polyfill'
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router/router'
import store from './vuex/store'
import api from './api/api'
import Vant from 'vant'
import 'vant/lib/index.css'
import infiniteScroll from 'vue-infinite-scroll'
Vue.use(infiniteScroll)
Vue.use(Vuex)
Vue.use(Vant)
Vue.prototype.$api = api

new Vue({
  router, // 通过 router 选项,提供了一种机制将 “路由” 从根组件注入到每一个子组件中,子组件能通过 this.$router 访问
  store, // 通过 store 选项,提供了一种机制将 “状态” 从根组件注入到每一个子组件中,子组件能通过 this.$store 访问
  render: h => h(App)
}).$mount('#app')

router.js

import Vue from 'vue'
import Router from 'vue-router'

const home = () => import('@/views/index/index.vue')
const airport = () => import('@/components/airport/airport.vue')
const orderDetail = () => import('@/views/order/order-detail.vue')

Vue.use(Router)
export default new Router({
  mode: 'hash',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: home
    },
    {
      path: '/airport',
      name: 'airport',
      component: airport
    },
    {
      path: '/orderDetail/:orderNo',
      name: 'orderDetail',
      component: orderDetail
    }
  ]
})

2. Usage

2.1. The first demo

  • HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <router-view></router-view>
</div>
  • JS
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定义路由
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 通过 router 配置参数注入路由从而让整个应用都有路由功能
const app = new Vue({
  router // (缩写) 相当于 router: router
}).$mount('#app')

By injecting the router, we can this.$router access the router within any component  , or  this.$route access the current route:

// Home.vue
export default {
  computed: {
    username () {
      return this.$route.params.username
    }
  },
  methods: {
    goBack () {
      window.history.length > 1
        ? this.$router.go(-1)
        : this.$router.push('/')
    }
  }
}

2.2. Dynamic route matching

That is, the matching when the request url contains dynamic parameters, similar to this form:  /user/:id , similar to @pathVariable in springMVC

Here is a basic chestnut to understand the usage:

  1. Request path: /user/:id
  2. Application scenario: For example, users with different IDs can be mapped to the User component
  3. Then in the User component, you can get the id attribute in the params parameter object on the dynamic url through this.$route.params.id 

You can set multiple "path parameters" in a route, and the corresponding values ​​will all be set to the  $route.params middle. E.g:

mode Match path $route.params
/user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }

In  $route.params addition, the $route object also provides other useful information, for example, $route.query (if there are query parameters in the URL), $route.hash and so on.

2.3. Nested routing

For example , there is usually a top rendering exit <router-view /> in App.vue

<template>
  <div id="app" class="app">
    <router-view />
  </div>
</template>

When the access / user / 1 format treat User outlet assembly to render the topmost <router-view /> in

At the same time, the User component contains nested rendering exits <router-view />

For example,  User add a <router-view /> to the template of the component  :

const User = {
  template: `
    <div class="user">
      <h2>User {
   
   { $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}

To render components in nested exits, you need VueRouter to use children configuration in  the parameters  :

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

children Configuration is routes an array of routing configuration like  configuration!

At this point, based on the above configuration, when you visit  /user/foo , User the exit will not render anything, because there is no matching sub-route. If you want to render something, you can provide an empty sub-route:

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome },

        // ...其他子路由
      ]
    }
  ]
})

2.4. Programmatic navigation

 

2.4.1. router.push(location, onComplete?, onAbort?)

Declarative Programmatic
<router-link :to="..."> router.push(...)

 

 

 

// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

Note: If provided  path, it params will be ignored!

Because the path option represents the complete URL, and params is part of the URL, there will be ambiguity at the same time!

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

 

2.4.2. router.replace(location, onComplete?, onAbort?)

It is  router.push very similar, the only difference is that it does not add a new record to history, but is the same as its method name—replace the current history record.

Declarative Programmatic
<router-link :to="..." replace> router.replace(...)

 

 

 

2.4.3. router.go(n)

The parameter of this method is an integer, which means how many steps forward or backward in the history record, similar  window.history.go(n).

// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)

// 后退一步记录,等同于 history.back()
router.go(-1)

// 前进 3 步记录
router.go(3)

// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)

 

2.5. Naming Routes

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user', // 给路由起个名字而已
      component: User
    }
  ]
})
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

  or 

router.push({ name: 'user', params: { userId: 123 }})

  You can call it!

 

2.6. Redirect

When the user visits  /a, the URL will be replaced with  /b, and then the matching route will be /b

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

2.7. Aliases

/a The alias of is  /b, which means that when the user visits  /b , the URL will remain as  /b, but the route matching will be  /a, just like the user visits  /a .

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

2.8. Routing component parameter transfer

As the name implies, during the routing process, the routing parameters are converted into component attributes, and the parameters are passed in the way of passing values ​​between components!

why do this?

Using $route it in a component  makes it highly coupled with its corresponding route, so that the component can only be used on certain URLs, limiting its flexibility.

2.8.1. Usage comparison

And  $route coupling

const User = {
  template: '<div>User {
   
   { $route.params.id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

By  props decoupling

const User = {
  props: ['id'],
  template: '<div>User {
   
   { id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true }
  ]
})

Boolean mode

If it  props is set  true, it route.params will be set as a component property.

Object mode

If it  props is an object, it will be set as a component property as it is. props Useful when it  is static.

const router = new VueRouter({
  routes: [
    { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
  ]
})

Function mode

You can create a function to return  props. This way you can convert parameters to another type, combine static values ​​with route-based values, and so on.

const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
  ]
})

The URL  /search?q=vue will  {query: 'vue'} be passed to the SearchUser component as an attribute  .

Guess you like

Origin blog.csdn.net/u014225733/article/details/94722013