Vue Router

时间:2022-07-26
本文章向大家介绍Vue Router,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.1 路由简介

1.1.1 概述

  路由的实质是一种对应关系,url 与资源之间的对应关系就是路由。路由分为前端路由和后端路由,后端路由是由服务器完成转发,前端路由是 hash(锚点) 的变化实现的。Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:  ♞ 嵌套的路由/视图表  ♞ 模块化的、基于组件的路由配置  ♞ 路由参数、查询、通配符  ♞ 基于 Vue.js 过渡系统的视图过渡效果  ♞ 细粒度的导航控制  ♞ 带有自动激活的 CSS class 的链接  ♞ HTML5 历史模式或 hash 模式,在 IE9 中自动降级  ♞ 自定义的滚动条行为

1.2 Vue Router 的使用

1.2.1 语法

☞ 安装

# npm 安装
npm install vue-router

# 使用 CDN
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

☞ 语法(srcrouter/index.js)

import Vue from 'vue'
import Router from 'vue-router'
// 增加这一行, 作用是引入 MyPage 这个组件
import MyPage from '@/components/MyPage'

Vue.use(Router)
export default new Router({
  routes: [
    // 增加下面几行, 表示定义了  /#/myPage 这个url
    {
      path: '/myPage',
      name: 'MyPage',	// 可以省略,加上 name 属性之后就是命名路由
      component: MyPage
    },
  ]
})
<!-- 视图中跳转方式 -->
<!-- 字符串 -->
<router-link to="myPage"> to apple</router-link>

<!-- 对象 -->
<router-link :to="{path:'myPage'}"> to apple</router-link>

<!-- 命名路由 -->
<router-link :to="{name: 'MyPage'}"> to apple</router-link>
// JS 中跳转方式
// 字符串
this.$router.push('/myPage')

// 对象
this.$router.push({ path: '/myPage' })

// 命名的路由
this.$router.push({ name: 'MyPage'})

☞ 说明   路由是所有前端框架中都必须具备的元素。 它定义了对于那个 URL(页面),应该由那个文件来处理。每个 vue 页面,都要对应一个路由。一般需要两个东西:vue 文件,负责展示页面;路由代码,让 url 与 vue 文件对应。路由中的相关属性: path:定义了 链接地址, name:为这个路由加个名字,方便以后引用,例如: this.$router.push({name: 'myPage'}) component:该路由由哪个 component 来处理。

1.2.2 示例

☞ 项目目录

☞ 组件(srccomponentsHelloWorld.vue)

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li>babel</li>
      <li>eslint</li>
      <li>router</li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li>Core Docs</li>
      <li>Forum</li>
      <li>Community Chat</li>
      <li>Twitter</li>
      <li>News</li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li>vue-router</li>
      <li>vuex</li>
      <li>vue-devtools</li>
      <li>vue-loader</li>
      <li>awesome-vue</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

☞ about 页面(srcviewsAbout.vue)

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

☞ home 页面(srcviewsHome.vue)

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'Home',
  components: {
    HelloWorld
  }
}
</script>

☞ 主页面(srcApp.vue)

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<style lang="less">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

☞ 路由(srcrouterindex.js)

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

Vue.use(VueRouter)

  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')
  }
]

const router = new VueRouter({
  routes
})

export default router

☞ 演示

1.2.3 路由的参数

☞ 普通参数

routes: [
  {
    path: '/blog',
    name: 'Blog'
  },
]

  对于上述路由我们想要传递参数可以在视图中使用 <router-link :to="{name: 'Blog', query:{id: 3} }">User</router-link>,也可以在 JS 中使用 this.

☞ 路由中声明的参数

routes: [
  {
    path: '/blog/:id',
    name: 'Blog'
  },
]

  对于这种路由中将参数声明了的,我们想要传递参数可以在视图中使用 <router-link :to="{name: 'Blog', params: {id: 3} }">User</router-link>,也可以在 JS 中使用 this.

1.2.4 动态路由

☞ 概述

  我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果。

模式

匹配路径

$route.params

/user/:username

/user/evan

{ username: ‘evan’ }

/user/:username/post/:post_id

/user/evan/post/123

{ username: ‘evan’, post_id: ‘123’ }

☞ 示例

routes: [
	// 动态路径参数 以冒号开头
	{ path: '/user/:id', component: User }
]


routes: [
	// 不用动态路由,需要配置一堆
	{ path: '/user/1', component: User },
	{ path: '/user/2', component: User },
	{ path: '/user/2', component: User },
]

1.2.5 嵌套路由

☞ 概述

  实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

☞ 示例

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

1.2.6 编程式导航

  除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以使用 router.push(location,onComplete,onAbort) 方法来实现。使用 router.push 方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。当你点击 <router-link> 时,router.push 方法会在内部调用,所以说,点击 <router-link :to="..."> 等同于调用 router.push(...)router.go(n) 这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

  注意:如果提供了 path 属性,params 属性会被忽略,query 属性并不属于这种情况。一般我们需要提供路由的 name 或手写完整的带有参数的 path。

1.2.7 重定向与别名

☞ 重定向

// 重定向可以通过 routes 配置来完成
routes: [
	{ path: '/a', redirect: '/b' }
]

// 重定向的目标也可以是一个命名的路由
routes: [
	{ path: '/a', redirect: { name: 'foo' }}
]

// 重定向甚至是一个方法,动态返回重定向目标
routes: [
	{ path: '/a', redirect: to => {
		// 方法接收 目标路由 作为参数
		// return 重定向的 字符串路径/路径对象
	}}
]

☞ 别名

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

routes: [
	{ path: '/a', component: A, alias: '/b' }
]