Vue Router入门


前言

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。


一、入门

当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们。

router-view将显示与 url 对应的组件。你可以把它放在任何地方,以适应你的布局。

实例:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>myRoute</title>
	</head>
	<body>
		<script src="https://unpkg.com/vue@3"></script>
		<script src="https://unpkg.com/vue-router@4"></script>

		<div id="app">
			<h1>Hello App!</h1>
			<p>
				<router-link to="/">Go to Home</router-link>|
				<router-link to="/about">Go to About</router-link>
			</p>
			<router-view></router-view>
		</div>
	</body>

	<script type="text/javascript">
		const Home = {
			template: '<div>Home</div>'
		}
		const About = {
			template: '<div>About</div>'
		}
		const routes = [{
				path: '/',
				component: Home
			},
			{
				path: '/about',
				component: About
			},
		]
		const router = VueRouter.createRouter({
			history: VueRouter.createWebHashHistory(),
			routes,
		})
		const app = Vue.createApp({})
		app.use(router)
		app.mount('#app')
	</script>
</html>

运行结果: 

通过调用 app.use(router),我们可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由。

二、动态路由匹配

 当我们需要将给定匹配模式的路由映射到同一个组件。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 。

 动态路由实例:

我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。

<router-link to="/users/abc">Go to User abc</router-link>|
<router-link to="/users/123">Go to User 123</router-link>
const User = {
   template: '<div>User {{ $route.params.id }}</div>',
}

const routes = [
  // 动态字段以冒号开始
  { path: '/users/:id', component: User },
]

 运行结果:

 路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。

响应路由参数的变化

 相同的组件实例将被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会被调用

 对同一个组件中参数的变化做出响应:

1. watch $route 对象上的任意属性,在这个场景中,就是 $route.params

const User = {
  template: '...',
  created() {
    this.$watch(
      () => this.$route.params,
      (toParams, previousParams) => {
        // 对路由变化做出响应...
      }
    )
  },
}

2. 使用 beforeRouteUpdate 导航守卫,它也可以取消导航

const User = {
  template: '...',
  async beforeRouteUpdate(to, from) {
    // 对路由变化做出响应...
    this.userData = await fetchUser(to.params.id)
  },
}

捕获所有路由或404Notfound路由

 常规参数只匹配 url 片段之间的字符,用 / 分隔。如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式在 路径参数 后面的括号中加入 正则表达式 :

const routes = [
  // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  { path: '/user-:afterUser(.*)', component: UserGeneric },
]

 在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将pathMatch 参数标记为可选可重复。这样做是为了让我们在需要的时候,可以通过将 path 拆分成一个数组,直接导航到路由

this.$router.push({
  name: 'NotFound',
  params: { pathMatch: this.$route.path.split('/') },
})

高级匹配模式

 Vue Router 使用自己的路径匹配语法,其灵感来自于 express,因此它支持许多高级匹配模式,如可选的参数,零或多个 / 一个或多个,甚至自定义的正则匹配规则。

 三、路由的匹配语法

 在参数中自定义正则

 当定义像 :userId 这样的参数时,我们内部使用以下的正则 ([^/]+) (至少有一个字符不是斜杠 / )来从 URL 中提取参数。这很好用,除非你需要根据参数的内容来区分两个路由。想象一下,两个路由 /:orderId 和 /:productName,两者会匹配完全相同的 URL,所以我们需要一种方法来区分它们。最简单的方法就是在路径中添加一个静态部分来区分它们:

const routes = [
  // 匹配 /o/3549
  { path: '/o/:orderId' },
  // 匹配 /p/books
  { path: '/p/:productName' },
]

 但在某些情况下,我们并不想添加静态的部分。由于,orderId 总是一个数字,而 productName 可以是任何东西,所以我们可以在括号中为参数指定一个自定义的正则

const routes = [
  // /:orderId -> 仅匹配数字
  { path: '/:orderId(\\d+)' },
  // /:productName -> 匹配其他任何内容
  { path: '/:productName' },
]

可重复的参数

 如需要匹配具有多个部分的路由,如 /first/second/third,应该用 *(0 个或多个)+(1 个或多个)将参数标记为可重复:

const routes = [
  // /:chapters ->  匹配 /one, /one/two, /one/two/three, 等
  { path: '/:chapters+' },
  // /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
  { path: '/:chapters*' },
]

 这将提供一个参数数组,而不是一个字符串,并且在使用命名路由时也需要传递一个数组

// 给定 { path: '/:chapters*', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 产生 /
router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href
// 产生 /a/b

// 给定 { path: '/:chapters+', name: 'chapters' },
router.resolve({ name: 'chapters', params: { chapters: [] } }).href
// 抛出错误,因为 `chapters` 为空 

 也可以通过在右括号后添加它们与自定义正则结合使用:

const routes = [
  // 仅匹配数字
  // 匹配 /1, /1/2, 等
  { path: '/:chapters(\\d+)+' },
  // 匹配 /, /1, /1/2, 等
  { path: '/:chapters(\\d+)*' },
]

可选参数

 可以通过使用 ? (0 个或 1 个)将一个参数标记为可选:

const routes = [
  // 匹配 /users 和 /users/posva
  { path: '/users/:userId?' },
  // 匹配 /users 和 /users/42
  { path: '/users/:userId(\\d+)?' },
]

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值