vue-router
传统的路由是针对服务器不同文件,这样路由的变动就会导致新页面加载,导致页面刷新。vue-router 实现了在 vue 组件基础上,不加载页面文件,而是更改部分页面组件的方式来展现不同路由时显示的内容。同时节约了客户端和服务端资源。
npm i vue-router@4
- vue-router 是通过 hook 的方式获取 router 对象并完成配置,然后以插件的方式挂载到app上面
// router.js
import { createRouter, createWebHistory} from 'vue-router'
import Login from '../components/Login'
import Register from '../components/Register'
const routes = [
{
path: '/login',
name: 'Login'
component: Login
},
{
path: '/register',
name: 'Register'
component: Register
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
- 在 main.js 中挂载
// main.js
import router from './router'
app.use(router)
- 在组件中使用路由
// App.vue
<router-link to="/login">Login</router-link>
<router-link to="/register">Register</router-link>
<hr>
// router-view 是显示组件的地方,也就是显示 Login 或者 Register 内容的地方
<router-view></router-view>
- 事件触发跳转
<template>
// 方式一 二
<button @click='toPage('/login')'>Login</button>
// 方式三
<button @click='toPage('Login')'>Login</button>
</template>
<script>
import { userouter } from 'vue-router'
const router = userouter()
// 方式一
function toPage(url) {
// 通过 push 方法实现跳转
router.push(url)
}
// 方式二
function toPage(url) {
// 传入一个对象
router.push({
path: url
})
}
// 方式三
function toPage(name) {
router.push({
name
})
}
</script>
- createWebHistory || createWebHashHistory
- 如果在login页面里面采用 WebHistory,那么 '/' 路径代表的就是localhost
- 而如果采用WebHashHistory,那么 '/' 路径代表 localhost/login#/
- 如果是单页面文件,选择 WebHistory 会简洁一点
- 如果是多页面文件, WebHashHistory 更容易区分前端路由和后端路由. 当然 WebHistory 也可以,个人更倾向于 WebHistory
const routes = [
{
path: '/login',
name: 'Login', // 给路由命名
component: Login
},
{
path: '/register',
name: 'Register',
component: Register
}
]
- 对应的跳转方式
<router-link :to="{name: 'Login'}">Login</router-link>
- 如果页面跳转不想被历史记录 需要加入 replace 属性给 router-link
<router-link replace to='/login'>Login</router-link>
- 事件跳转不加入历史记录,将 push 方法更变为 replace 方法即可
router.replace('/login')
router.go(n) // 跳转到历史记录向后 n 个记录的页面
router.back(n) // 跳转到历史记录向前 n 个记录的页面
- 通过在 push 或者 replace 方法 中传入的对象里面加入 query 或者 params 属性的方式可以传参
- 在组件中,通过 router.query.xxx || router.params.xxx 来获取参数
- 这种方式在地址栏的 url 中会携带参数并显示出来
router.push({
path: '/info',
query: item
})
// info
<div>Price: {{ router.query.price }}</div>
- 这种方式 url 不会携带参数
router.push({
name: 'Info',
params: item
})
// info
<div>Price: {{ router.params.price }}</div>
- 在设定路由的时候,可以添加一个动态参数
const routes = [
{
path: '/detial/:id'
component: Detial
}
]
- 在传参的时候传入包含对应参数的对象即可
const id = item.id
router.push({
path: '/detial'
query: {
id
}
// OR
query: item
})
- params 方式也可以实现动态传参
- 通过 children 属性来实现路由嵌套
const routes = [
{
path: '/user'
component: User,
children: [
{
path: 'login' // 注意这里不加 /
component: Login
}
]
}
]
- 通过命名视图,一个路径可以对应多个视图组件,并且可以通过名称进行控制
import Login from '../components/Login'
import Register from '../components/Register'
const routes = [
{
path: '/login'
// 这里 component 是一个对象
component: {
login: Login
}
},
{
path: '/register'
// 这里 component 是一个对象
component: {
register: Register
}
}
]
<template>
<router-view name='login'></router-view>
<hr>
<router-view name='register'></router-view>
</template>
const routes = [
{
path: '/'
redirect : '/login'
// OR
redirect: {
path:'/login'
}
// OR
redirect: to => { // to 是被重定向的路由信息
return {
path: '/login'
query: xxx // 这里可以传参
}
}
},
{
path: '/login'
component: ...
}
]
const routes = [
{
path: '/',
alias: ['/root'] // 这里设置别名后,访问 /root 就相当于访问 /
}
]
- 官方链接
- 所谓导航守卫,就是当网站被访问,或者站内路径改变的时候执行的一些控制代码。
- 导航守卫有前置和后置之分,前置守卫控制是否进行跳转和预置动作,后置为跳转以后执行的前置代码。
- 按照作用范围,导航守卫可以分为全局,路径,组件级别。
- 全局导航守卫
// jump.js
export default function(router) {
router.beforeEach((to, from) => { // afterEach 就是后置守卫
if(to.name === 'Index' && true) {
return {name: 'Login'}
}
})
router.afterEach((to, from) => {
if(to.name === 'Index') {
console.log('oh yeah')
}
})
}
- 页面级别的导航守卫
{
path: '/index',
name: 'Index',
components: {
main: Index
},
beforeEnter: (to, from) => {
if(true) {
return {name: 'Login'}
}
}
}
- 组件内导航守卫,和指定组件的 name 一样,不能使用 setup 语法糖
<script setup>
const a = 12
</script>
<script>
export default {
beforeRouteEnter(to, from, next) {
if(false) {
return next({name: 'Login'})
}
next()
}
}
</script>
<template>
<h1>Index page</h1>
<p>{{ a }}</p>
</template>
<style lang="scss" scoped>
</style>
- route 的 meta 属性用来携带路由相关信息
const routes = [
{
path: '/posts',
component: PostsLayout,
children: [
{
path: 'new',
component: PostsNew,
// 只有经过身份验证的用户才能创建帖子
meta: { requiresAuth: true },
},
{
path: ':id',
component: PostsDetail
// 任何人都可以阅读文章
meta: { requiresAuth: false },
}
]
}
]
- 导航守卫快捷获取 meta 信息
router.beforeEach((to, from) => {
// 而不是去检查每条路由记录
// to.matched.some(record => record.meta.requiresAuth)
if (to.meta.requiresAuth && !auth.isLoggedIn()) {
// 此路由需要授权,请检查是否已登录
// 如果没有,则重定向到登录页面
return {
path: '/login',
// 保存我们所在的位置,以便以后再来
query: { redirect: to.fullPath },
}
}
})
- router 和 route 在组件中的作用,二者分别可以从vue-router对象的 useRouter 和 useRoute 方法获得实例。
- router 对象通过其 push 等方法可以添加 meta 并触发页面跳转。
- route 对象则携带了 meta 数据,通过 route.meta 就可以得到数据。query的方式同理
- 需要注意的是,params 在通过这种方式传参的时候会报错,不建议使用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话