Vue中如何使用路由实现页面间的消息传递?
Vue作为最近几年非常火热的前端框架之一,其路由功能也得到了广泛的应用。通过路由,我们可以实现SPA(Single Page Application,单页面应用)的开发,同时还可以实现页面间的切换和传递数据。下面我们就来详细了解一下Vue中如何使用路由实现页面间的消息传递。
1. Vue路由初探
在正式探讨Vue中路由进行消息传递的实现方法之前,我们先来回顾一下Vue中路由的基本知识。
要使用路由功能,首先需要安装和引入Vue的路由组件:
npm install vue-router -save
然后在Vue的入口文件(main.js)中引入和使用路由:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [{
path: '/home',
component: Home
}]
})
new Vue({
router,
render: h => h(App)
}).$mount('#app')
在上面的代码中,我们首先引入了Vue和Vue Router库,然后通过Vue.use()方法引入Vue Router插件。接着,我们定义了一个路由实例,并传入了一些路由配置信息。其中,routes数组用于配置各个页面的路由信息,其中path表示路由路径,component表示该路径对应的组件。最后,我们将定义好的路由实例通过new Vue()的router选项进行注册,从而使整个应用程序具备路由功能。
2. Vue路由传参
有了路由功能,我们可以在组件之间实现跳转,但是如何在组件之间传递数据呢?这就需要用到Vue路由的传参功能。
Vue路由有两种传参方式,分别是通过params和query传递参数:
2.1 params传参
params传参是通过路由路径中的动态参数来实现的。例如,我们定义一个用户详情页面的路由,路径为/user/:id,其中:id为动态参数,表示用户的id。那么我们在跳转到该路由时,可以通过params将用户信息传递给该组件:
// 声明路由规则
const router = new VueRouter({
routes: [{
path: '/user/:id',
component: UserDetail
}]
})
// 跳转时传参
this.$router.push('/user/' + userId)
在上面的代码中,我们首先声明路由规则,其中使用了动态参数:id,表示用户的id。然后在跳转页面时,我们通过this.$router.push()方法,并将用户id作为参数来跳转到/user/:id页面。在目标组件中,可以通过this.$route.params来访问该参数:
export default {
mounted() {
console.log(this.$route.params.id)
}
}
2.2 query传参
query传参是通过在路由路径中添加查询参数来实现的,类似于URL中的查询语句。例如,我们定义一个搜索页面的路由,路径为/search,那么我们在跳转到该页面时,可以通过query传递搜索关键字参数:
// 跳转时传参
this.$router.push({
path: '/search',
query: { keyword: 'Vue' }
})
在上面的代码中,我们在跳转时使用了一个对象,其中path表示跳转路径,query表示查询参数。在目标组件中,我们可以通过this.$route.query访问该参数:
export default {
mounted() {
console.log(this.$route.query.keyword)
}
}
3. Vue路由跳转方法
除了通过push方法跳转页面以外,Vue路由还提供了其他的跳转方法,分别是replace和go:
3.1 replace方法
replace方法可以用于替换当前页面的历史记录,从而实现无法返回的效果。例如,我们在登录之后需要跳转到首页,而此时我们希望用户无法通过浏览器的返回按钮返回到登录页面,那么我们可以使用replace方法:
this.$router.replace('/home')
3.2 go方法
go方法可以用于在浏览器的历史记录中前进或后退若干步。例如,我们需要在当前页面的基础上跳转到前一个页面,那么我们可以使用go(-1):
this.$router.go(-1)
4. Vue路由守卫
除了简单的页面跳转和传参之外,Vue路由还提供了路由守卫的功能,从而在路由跳转时控制页面的权限和数据访问。
路由守卫包括全局守卫、路由守卫和组件守卫三种类型。全局守卫是在整个应用程序范围内检测路由变化的,路由守卫是在检测到路由变化时进行的处理,而组件守卫则是在组件内部进行的处理。
下面我们详细介绍一下路由守卫的实现方法:
4.1 全局守卫
全局守卫是在Vue路由实例中定义的,可以在任何组件中使用。全局守卫包括beforeEach、beforeResolve和afterEach三种:
- beforeEach:在路由变化前触发,用于检测用户是否有权限访问某个路由;
- beforeResolve:在路由确认时触发,用于异步地获取路由数据;
- afterEach:在路由变化后触发,用于处理页面跳转后的逻辑。
下面我们通过一个例子,来演示如何使用全局守卫实现页面权限控制:
const router = new VueRouter({
routes: [
{
path: '/',
component: Home,
meta: { requiresAuth: true }
},
{
path: '/login',
component: Login
}
]
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next()
}
})
在上面的代码中,我们首先定义了两个路由,其中/表示首页,需要进行权限验证;/login表示登录页面。接着,我们在路由实例中定义了一个beforeEach守卫,通过to.matched.some()方法判断其是否需要进行认证并使用auth.loggedIn()方法实现登录验证。如果未登录,则跳转到/login页面,并使用query参数记录当前页面,从而在登录成功后返回该页面。如果已登录,则允许访问该页面。
4.2 路由守卫
路由守卫是在路由级别上进行控制,可以在某个路由或者路由组中进行配置。路由守卫包括beforeEnter、beforeRouteUpdate、beforeRouteLeave三种:
- beforeEnter:在某个路由被激活之前触发,用于检测用户是否有权限访问;
- beforeRouteUpdate:在路由信息发生变化(例如查询参数变化)时触发;
- beforeRouteLeave:在离开某个路由或路由组之前触发,用于处理页面数据的保存或清理。
下面我们通过一个例子,来演示如何使用路由守卫实现页面数据的保存和清理:
const router = new VueRouter({
routes: [
{
path: '/article/:id',
component: Article,
props: true,
beforeRouteLeave(to, from, next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
}
]
})
在上面的代码中,我们定义了一个/article/:id路由,表示文章详情页面。其中通过props: true将动态参数id作为组件的props传递。接着,在该路由中定义了一个beforeRouteLeave守卫,用于在离开页面之前提示用户是否保存未保存的数据。如果用户确认离开,则调用next()方法;否则调用next(false)方法,表示不允许离开当前页面。
4.3 组件守卫
组件守卫是在组件内部进行控制的,可以通过Vue的生命周期函数和watcher完成。组件守卫包括beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave三种:
- beforeRouteEnter:在路由激活之前和组件被创建之后触发,用于获取异步数据;
- beforeRouteUpdate:在路由参数发生变化时触发,用于获取新的数据;
- beforeRouteLeave:在离开之前触发,用于保存组件内部的数据。
下面我们通过一个例子,来演示如何使用组件守卫实现异步数据的加载和保存:
export default {
data() {
return {
article: null
}
},
beforeRouteEnter(to, from, next) {
axios.get('/api/article/' + to.params.id).then(response => {
next(vm => {
vm.article = response.data.article
})
})
},
beforeRouteUpdate(to, from, next) {
axios.get('/api/article/' + to.params.id).then(response => {
this.article = response.data.article
next()
})
},
beforeRouteLeave(to, from, next) {
const answer = window.confirm('Do you want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
}
在上面的代码中,我们定义了一个文章详情组件,并通过axios加载异步数据。在组件中使用beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave守卫,分别处理异步数据加载、路由参数更新和离开组件时保存数据的逻辑。具体而言,在beforeRouteEnter守卫中,我们通过axios加载异步数据,在后续next()函数中将数据绑定到组件中;在beforeRouteUpdate守卫中,我们再次通过axios获取新数据,并直接更新组件中的article对象;在beforeRouteLeave守卫中,我们提示用户是否保存未保存的数据,并使用next()或next(false)控制是否离开组件。
5. 总结
通过本文的介绍,我们详细了解了Vue路由的基本知识,以及如何通过路由实现页面间的消息传递。具体而言,我们介绍了路由传参、路由跳转方法和路由守卫的使用方法,并通过具体的例子演示了如何在组件之间传递异步数据和控制页面权限和数据访问。相信本文对于Vue初学者来说会有很大帮助,也希望能对大家掌握Vue路由实现消息传递的技能有所帮助。