共计 6414 个字符,预计需要花费 17 分钟才能阅读完成。
1. 简介
vue-router
是官方提供的路由插件。Vue 中的路由其实就是路径和组件之间的对应关系,因为 vue 是单页应用类网站,所以创建的网站都在一个页面中。当需要展示不同的内容时,就需要通过修改浏览器的访问路径,来达到根据路径展示不同组件的目的。
官方文档:https://router.vuejs.org/zh/
可以使用 <router-link>
组件进行导航,使用 <router-view>
做为路由出口,即点击导航所对应的组件。
2. 简单使用
vue2 中使用 vue-router
分为以下几个步骤:
- 安装
vue-router
- 引入
vue-router
- 注册
vue-router
插件 - 创建
VueRouter
实例 - 将
VueRouter
注入Vue
实例
其中第一步当然是在控制台完成。
npm install vue-router
接下来要创建 VueRouter
,一般会在 src
目录下新建一个 router/index.js
文件。
// 引入 vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/components/Home.vue';
import About from '@/components/About.vue';
// 注册 vue-router 插件。
// 告诉 Vue.js 使用 VueRouter 插件,所有插件使用之前都需要进行注册
Vue.use(VueRouter)
// 创建 VueRouter 实例
export default new VueRouter({
routes: [{
path: '/',
name: 'home',
component: Home
}, {
path: '/about',
name: 'about',
component: About
}]
});
在 main.js
中引入 VueRouter
,并注入。
import router from './router'
new Vue({
el: '#app',
components: { App },
template: '<App/>',
router
})
在组件中这样使用即可。
<template>
<div id="app">
<h1>Hello App!</h1>
<div class="nav">
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
</div>
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
}
</script>
<style scoped>
.content {
background-color: skyblue;
}
</style>
3. 嵌套路由
一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构。
其中 routes 定义如下:
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
component: Home,
children: [
{ path: 'foo', component: Foo },
{ path: 'bar', component: Bar }
]
}, {
path: '/about',
name: 'about',
component: About
}]
});
可以看见 Foo
和 Bar
组件都在 /home
路由下,他们的完整路由为 /home/foo
和 /home/bar
。所以,此时 Home
应该包含 Foo
和 Bar
组件。
Home.vue
内容如下:
<template>
<div>
<h2>我是Home组件</h2>
<router-link to="/home/foo">Foo</router-link>
<router-link to="/home/bar">Bar</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
HelloWorld.vue
<template>
<div id="app">
<h1>我是HelloWorld组件</h1>
<div class="nav">
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
</div>
<div class="content">
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld'
}
</script>
<style scoped>
.content {
background-color: skyblue;
}
</style>
效果:
4. 命名路由
定义路由时,可以看见不仅定义了路径,同时还定义了名称,所以导航也可以指定为路由的名称。
使用方式如下:
<router-link to="/home">Home</router-link>
<!-- 等价于 -->
<router-link :to="{ path: '/home' }">Home</router-link>
<!-- 如果 /home 对应的名称为 home -->
<router-link :to="{ name: 'home' }">Home</router-link>
5. 路由传参
5.1 动态路由参数
使用动态路由参数,可以在路由路径中包含参数,这些参数可以在路由组件中通过 $route.params来获取。
路由定义:
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
component: Home
}, {
path: '/about/:id',
name: 'about',
component: About
}]
});
路由链接:
<router-link to="/about/123">About</router-link>
在 About
组件中,可以通过如下方式获取参数:
let id = this.$route.params.id
5.2 Props传参
可以通过路由配置中的 props
选项,将路由组件需要的参数直接作为 props
传递给组件。这种方式需要将 $route
对象的内容直接传递给组件,可以在组件中像普通 props
一样访问这些参数。
路由定义:
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
component: Home
}, {
path: '/about/:id',
name: 'about',
props: true
component: About
}]
});
路由链接:
<router-link to="/about/123">About</router-link>
在 About
组件中,可以通过如下方式获取参数:
props: [ 'id'],
5.3 查询参数
通过查询参数传递数据,参数会出现在URL中的 ?
后面,并且可以通过 $route.query
来获取。
路由定义:
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
component: Home
}, {
path: '/about',
name: 'about',
component: About
}]
});
路由链接:
<router-link :to="{ path: '/about', query: { id: 123 }}">About</router-link>
在 About
组件中,可以通过如下方式获取参数:
let id = this.$route.query.id
5.4 通过导航钩子传参
...
6. 重定向和别名
6.1 重定向
例如增加一个 /
的路由,访问该路径默认会跳转到 home
路由。
const router = new VueRouter({
routes: [{
path: '/',
redirect: { name: 'home' },
//redirect: { path: '/home' }
},{
path: '/home',
name: 'home',
component: Home
}, {
path: '/about',
name: 'about',
component: About
}]
});
甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({
routes: [{
path: '/test/:id',
redirect: to => {
// 访问 /test/100 => /home?id=100
return { path: '/home', query: { id: to.params.id } }
}
},{
path: '/home',
name: 'home',
component: Home,
children: [
{ path: 'foo', component: Foo },
{ path: 'bar', component: Bar }
]
}, {
path: '/about',
name: 'about',
component: About
}]
});
在写 redirect
的时候,可以省略 component
配置,因为它从来没有被直接访问过,所以没有组件要渲染。唯一的例外是嵌套路由。如果一个路由记录有 children
和 redirect
属性,它也应该有 component
属性。
6.2 别名
上述例子中,重定向 /
路由会导致浏览器 url 发生改变 /home
。但是可以使用重命名,访问 /
时,浏览器 url 不发生改变,但页面内容仍然是和 /home
路由一样的内容。
const router = new VueRouter({
routes: [{
path: '/home',
name: 'home',
alias: "/",
component: Home
}, {
path: '/about',
name: 'about',
component: About
}]
});
通过别名,可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 /
开头,以使嵌套路径中的路径成为绝对路径。甚至可以将两者结合起来,用一个数组提供多个别名。
7. 历史记录模式
历史记录模式分为两种:
- hash 模式。特定是有
#
,SEO 效果差,适用于后台管理系统。 - history 模式。和传统
url
类似,适合需要搜索引擎收录的网站。
之前创建的 VueRouter
实例,默认都是 hash 模式。所以都是带 #
的。
如果需要修改为 history 模式,指定 mode
即可。
const router = new VueRouter({
//mode: 'hash',
mode: 'history',
routes: [{
path: '/home',
name: 'home',
alias: "/",
component: Home
}, {
path: '/about',
name: 'about',
component: About
}]
});
8. 编程式导航
除了使用
在组件中可以使用 this
对象,拿到 router
实例,然后调用 router
的 api 进行路由的修改。(这里修改的其实就是浏览器的地址)
- 使用
$router.push(location)
:导航到一个新的 URL,可以是一个字符串路径或一个描述地址的对象。例如:
// 字符串路径
this.$router.push('/home')
// 对象
this.$router.push({ path: '/home' })
// 带查询参数
this.$router.push({ path: '/home', query: { key: 'value' } })
-
使用
$router.replace(location)
:类似$router.push()
,但是不会在导航历史记录中留下记录,所以点击后退按钮无法返回上一个页面。用法与$router.push()
相同。 -
使用
$router.go(n)
:在导航历史记录中向前或向后移动多少步。例如:
// 后退一步
this.$router.go(-1)
// 前进一步
this.$router.go(1)
- 使用
$router.back()
和$router.forward()
:分别用于后退和前进。这两种方式相当于$router.go(-1)
和$router.go(1)
。例如:
// 后退
this.$router.back()
// 前进
this.$router.forward()
这些方法可以需求选择使用,比如根据用户的操作进行页面导航、处理表单提交后的页面跳转等。
9. 导航守卫
导航守卫是 Vue Router
提供的一种机制,用于在路由导航过程中进行拦截和控制。它允许你在路由导航发生前、发生时、发生后等不同的阶段执行一些自定义逻辑。Vue Router 提供了全局导航守卫、路由独享守卫和组件内的守卫。
9.1 全局导航守卫
全局导航守卫包括 beforeEach
、beforeResolve
和 afterEach
,它们分别在路由导航之前、导航被确认之前、导航成功完成之后触发。这些守卫可以在 Vue Router 实例上直接设置:
const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
console.log(" 在路由导航之前执行的逻辑");
});
router.beforeResolve((to, from, next) => {
console.log("在导航被确认之前执行的逻辑");
});
router.afterEach((to, from) => {
console.log("在导航成功完成之后执行的逻辑");
});
以上 beforeEach
和 beforeResolve
均可以使用 next(false)
来终端导航,并且如果导航没问题,必须使用 next()
放行。
9.2 路由独享守卫
路由独享守卫是针对某个特定路由设置的守卫,通过在路由配置中使用 beforeEnter 字段来定义:
const router = new VueRouter({
//mode: 'hash',
mode: 'history',
routes: [{
path: '/home',
name: 'home',
component: Home,
beforeEnter: (to, from, next) => {
// 在进入 '/foo' 路由之前执行的逻辑
}
}, {
path: '/about',
name: 'about',
component: About
}]
});
9.3 组件内的守卫
组件内的守卫包括 beforeRouteEnter
、beforeRouteUpdate
和 beforeRouteLeave
,它们分别在组件被创建、更新和销毁时触发。
export default {
name: 'Home',
beforeRouteEnter(to, from, next) {
// 注意:在这里无法通过 this 访问组件实例,因为组件还未被创建
console.log("在进入该组件路由之前执行的逻辑");
next();
},
beforeRouteUpdate(to, from, next) {
// 可以访问组件实例
console.log("在当前路由改变,但是该组件被复用时执行的逻辑");
next();
},
beforeRouteLeave(to, from, next) {
// 在离开该组件的路由时执行的逻辑
console.log("在离开该组件的路由时执行的逻辑");
next();
}
}
提醒:本文发布于239天前,文中所关联的信息可能已发生改变,请知悉!