知识介绍
什么是Vue Router?
Vue Router 是 Vue.js 官方的路由管理器,它深度集成了 Vue.js 的核心功能,使得开发者能够轻松地构建单页面应用(SPA)。Vue Router 提供了声明式的路由配置,允许你定义 URL 路径与要渲染的组件之间的映射关系,同时支持嵌套路由、动态路由参数、命名视图、导航守卫等功能。
什么是路由守卫?
路由守卫是 Vue Router 中用于控制导航的一种机制,它们是一系列的钩子函数,可以在路由转换的过程中被调用,从而实现对用户导航行为的控制。路由守卫可以用于:
- 验证用户权限:比如在用户访问需要登录才能看到的页面前检查用户是否已登录。
- 预加载数据:在显示新组件之前从服务器获取数据。
- 清理资源:在离开页面时清除不再需要的数据或资源,避免内存泄漏。
- 导航重定向:基于某些条件将用户重定向到另一个路由。
接下来,我们将通过一个路由实例,来学习路由守卫的应用。
正文
简单的登陆表单
- 显示一个登录页面,包含用户名和密码输入框以及登录按钮。
- 使用
v-model
指令绑定输入框的值到username
和password
变量。 - 在表单提交时调用
handleSubmit
函数进行登录验证。 - 在
handleSubmit
函数中,如果用户名为admin
且密码为123456
,则将isLoggedIn
设置到localStorage,并跳转到首页。 - 如果用户名或密码错误,则弹出警告框提示用户。
- 使用
onMounted
钩子函数检查localStorage中的isLoggedIn
,如果已登录,则在500毫秒后跳转到首页。
<template>
<div class="container mx-auto p-4">
<h1 class="text-3xl font-bold mb-4">Login</h1>
<form @submit.prevent="handleSubmit">
<div class="mb-4">
<label for="username"
class="block text-gray-700 text-sm font-bold mb-2">
Username:
</label>
<input
required
type="text" id="username" v-model="username"
class="shadow appearance-none border rounded w-full
py-2 px-3 text-gray-700 leading-tight focus:outline-none
focus:shadow-outline"
/>
</div>
<div class="mb-6">
<label for="password"
class="block text-gray-700 text-sm font-bold mb-2">
Password:
</label>
<input
required
type="password" id="password" v-model="password"
class="shadow appearance-none border rounded w-full
py-2 px-3 text-gray-700 leading-tight focus:outline-none
focus:shadow-outline"
/>
</div>
<button
type="submit"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold
py-2 px-4 rounded focus:outline-none focus:shadow-outline"
>Login</button>
</form>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const username = ref('')
const password = ref('')
const handleSubmit = () => {
if (username.value == 'admin' && password.value == '123456') {
localStorage.setItem('isLoggedIn', 'true')
router.push('/')
} else {
alert("用户名或密码错误")
}
}
onMounted(() => {
if (localStorage.getItem('isLoggedIn')) {
console.log('不用重新登录');
setTimeout(() => {
router.push('/')
}, 500)
}
})
</script>
创建路由实例
- 首先,通过
import
语句引入createRouter
和createWebHashHistory
方法。 - 然后,使用
createRouter
方法创建一个路由实例router
,并传入一个配置对象。在配置对象中,设置了history
为createWebHashHistory()
,表示使用哈希模式的路由历史记录。routes
是一个数组,包含了各个路由规则的配置。 - 在
routes
数组中,每个元素都是一个路由规则的配置对象。其中,path
表示路由的路径,name
表示路由的名称,component
表示该路由对应的组件。例如,第一个路由规则表示根路径/
对应的组件是Home.vue
。 - 在第三个路由规则中,
path
为/post/:id
,其中id
是一个动态参数,表示文章的ID。在路由匹配到该规则时,可以通过this.$route.params.id
获取到具体的ID值。 - 在第四个路由规则中,
meta
属性表示该路由的元数据,其中requireAuth
表示该路由需要用户认证才能访问。 - 最后,通过
export default
将router
实例导出,供其他模块使用。 - 在代码的最后,使用了
router.beforeEach
方法设置了一个全局的路由守卫。在每个路由切换之前,都会执行这个守卫函数。在守卫函数中,通过判断当前路由的meta.requireAuth
属性,来决定是否需要用户认证。如果需要认证,就检查本地存储中的isLoggedIn
值,如果已登录就继续前进,否则重定向到登录页面。如果不需要认证,就直接前进到下一个路由。
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue')
},
{
path: '/post/:id',
name: 'Detail',
component: () => import('../views/Detail.vue')
},
{
path: '/login',
name: 'Login',
component: () => import('../views/Login.vue')
},
{
path: '/cart',
name: 'Cart',
meta: {
requireAuth: true
},
component: () => import('../views/Cart.vue')
}
]
})
// 路由守卫
router.beforeEach((to, from, next) => {
// console.log(to, from, '????????????');
// next({path: '/login'})
if (to.meta.requireAuth) {
if (localStorage.getItem('isLoggedIn')) {
next()
} else {
next({path: '/login'})
}
} else {
next()
}
})
export default router
实现效果
代码源
半成品项目,实现了路由守卫和部分其他功能。