路由官网 router
路由指的是地址 url 与组件的映射关系,根据不同的 url 地址展示不同的内容或页面,通过 url 的变化实现页面的局部变化,而不用整体刷新页面。
引入
- 在一开始使用
npm create vue@latest
创建项目的时候,可以选择是否添加 Router。
- 或者可以使用
npm install vue-router@4
引入
使用
vue
</template>
// 将显示与 url 对应的组件。
<RouterView />
</template>
<script setup lang="ts">
import { RouterView } from "vue-router";
</script>
router.ts
ts
// router.ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
// 路由的模式
history: createWebHistory(import.meta.env.BASE_URL),
// 路由规则
routes: [
{
path: '/',
name: 'index',
component: () => import('@/views/index.vue'),
redirect: '/home',
children: [
{
path: '/home',
name: 'home',
component: () => import('@/views/home/index.vue')
},
]
},
{
path: "/:pathMatch(.*)*",
component: () => import('@/views/error/404.vue')
},
]
})
export default router
router.ts 暴露出的 router 给到 main.ts 中使用
ts
// mian.ts
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
createRouter
创建一个可以被 Vue 应用使用的 Router 实例。
createWebHistory
路由器使用的历史记录模式。也可以使用 createWebHashHistory,hash 模式。
createWebHistory 中传递了一个参数,第一参数是为基准路径,它被预置到每个 URL 上。例如传递的是 v3 ,则路径为 vuejs.com/v3
。但是上面文件中传递的是 import.meta.env.BASE_URL
,根据项目根目录下的 env 文件
。
env 文件
-
.env.development,开发环境下的环境变量文件。
-
.env.production,生成环境下的环境变量文件。
js
# 页面标题
VITE_APP_TITLE = v3网页
# 生产环境配置
VITE_APP_ENV = 'production'
# 生产环境基础路径
VITE_APP_BASE_API = '/prod-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip
路由规则 routes
createRouter 传递的对象属性 routes 为添加到路由器的初始路由列表。
js
{
path: '/',
name: 'index',
component: () => import('@/views/index.vue'),
redirect: '/home',
meta: {
name: '主页',
}
children: []
}
- path,路由跳转的路径。
- name,记录路由的唯一名称。
- component,路由组件。
- redirect,当访问到当前 path 路径时,重定向到该 redirect 值的路由 path 。
- children,嵌套路由,为该路由底下的子路由。
- meta,可以将任何信息添加到该字段上。
路由模式
history
js
const router = createRouter({
history: createWebHistory(),
routes: [ ..., ],
})
hash
它在内部传递的实际 URL 之前使用了一个哈希字符(#
)。由于这部分 URL 从未被发送到服务器,所以它不需要在服务器层面上进行任何特殊处理。
js
const router = createRouter({
history: createWebHashHistory(),
routes: [ ..., ],
})
route 和 router
- router 全局路由对象
- route 当前路由信息
js
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
let router = useRouter()
路由跳转
RouterLink
可以通过完整路径、name 进行跳转
vue
<RouterLink to="/ability">功能</RouterLink>
<RouterLink :to="{name: 'ability'}">功能</RouterLink>
useRouter
在进行跳转可以选择 push 或 replace。
- push,将新的路由添加到历史记录中,同时会导航到该路由页面,可以返回上一条记录。
- replace,会替换当前的路由记录,而不会添加新的历史记录。
js
import { useRouter } from 'vue-router'
let router = useRouter()
// 通过 path
router.push('/library')
// 通过对象形式
router.push({
path: '/library'
})
// 通过 name
router.push({
name: "library"
})
路由传参
标签传参
html
// 不需要路由配置
<RouterLink :to="{path:'/home',query:{name: '张三'}}">home</RouterLink>
// 需要路由配置
{
path: '/home/:name/:age',
name: 'home',
component: () => import('@/views/home/index.vue')
},
<RouterLink :to="{name:'home',params:{name: 1,age: 123}}">home</RouterLink>
<RouterLink :to="{path:'/home/1/123'}">home</RouterLink>
query
query传递的参数会显示在地址栏中,其格式是 /home?name=张三&age=18
js
// 传递
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
path: "/home",
query: {
name: "张三",
age: 18
}
})
// 获取
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query) // {name: "张三", age: 18}
params
传递动态参数,其中?
表示可传可不传,其格式是 /home/张三/18
js
// 配置
{
path: '/home/:name/:age?',
name: 'home',
component: () => import('@/views/home/index.vue')
},
// 传递
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
path: "/home/张三/18",
})
// 或
router.push({
name: "home",
params: {
name: '张三',
age: 18
}
})
// 获取
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params) // {name: "张三", age: 18}
history state
js
// 传递
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
name: "home",
state: {
name: 1,
age: 11
}
})
// 获取
console.log(history.state)
路由守卫
全局路由守卫
- to,要跳转目的路由的信息
- from,当前路由的信息
- next,通行函数
全局前置守卫 beforeEach
在路由跳转前触发,这个钩子作用主要是用于登录验证,也就是路由还没跳转提前告知,以免跳转了再通知就为时已晚
js
// permission.ts
import router from './router'
router.beforeEach((to, from, next)=>{
console.log('全局导航路由守卫~~~~~~~~~~~~',to, from)
next()
})
// 使用
// main.ts
import './permission'
全局后置守卫 afterEach
它是在路由跳转完成后触发,它发生在beforeEach和beforeResolve之后,beforeRouteEnter(组件内守卫)之前。钩子不会接受next函数也不会改变导航本身
js
router.afterEach((to,from)=>{})
全局解析守卫 beforeResolve
这个钩子和beforeEach类似,也是路由跳转前触发,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,即在 beforeEach 和 组件内beforeRouteEnter 之后,afterEach之前调用。
js
router.beforeResolve((to,from,next)=>{})
组件内守卫
beforeRouteEnter
在setup外新增一个script如何使用setup内函数
js
<script>
import {defineComponent} from 'vue'
export default defineComponent({
beforeRouteEnter(to, from, next){
console.log('beforeRouteEnter',to,from)
next()
}
})
</script>
onBeforeRouteUpdate
js
import { onBeforeRouteUpdate } from 'vue-router';
onBeforeRouteUpdate((to,from)=>{
console.log('组件 onBeforeRouteUpdate',to,from)
})
onBeforeRouteLeave
js
import { onBeforeRouteLeave } from 'vue-router';
onBeforeRouteLeave((to,from,next)=>{
console.log('组件 onBeforeRouteLeave')
})
路由独享守卫 beforeEnter
在 main.js 中使用,路由独享守卫是在路由配置页面单独给路由配置的一个守卫
js
routes: [
{
path: '/library',
component: library,
beforeEnter: (to, from, next) => {
next()
}
}
]