Vue3-06_路由
路由
后台路由是根据请求url,匹配请求处理的后台模块(路径)
前台根据访问路径,决定显示的内容。
路由就是: 访问hash 与内容的对应关系
路由的工作方式
- 用户点击页面的路由链接
- 导致url地址栏中的Hash值发生了变化
- 前端路由监听到Hash地址的变化
- 前端路由将当前Hash地址对应的组件渲染在浏览器中。
如何实现一个路由
核心逻辑:
在created 函数中通过 window.onhashchange 监听路由变化触发组件切换。
核心代码如下:
<template><a href="#/tab1">tab1</a><a href="#/tab2">tab2</a><a href="#/tab3">tab2</a><component :is="comName"></component>
</template><script>
import Tab1 from './components/Tab1.vue';
import Tab2 from './components/Tab2.vue';
import Tab3 from './components/Tab3.vue';export default {name: 'App',components: {Tab1,Tab2,Tab3},created() {window.onhashchange = () => {switch (location.hash) {case "#/tab1":this.comName = "tab1"breakcase "#/tab2":this.comName = "tab2"breakcase "#/tab3":this.comName = "tab3"break}}},data() {return {comName: "Tab1"}}
}
</script>
使用vue-router
基本用法-如何使用
安装
https://router.vuejs.org/zh/installation.html
定义组件
使用链接与占位符
使用 <router-link> 标签来声明路由链接,并使用 <router-view>标签来声明路由占位符
创建路由模块
①从vue-router 中按需导入两个方法
②导入需要使用路由控制的组件
③创建路由实例对象
④向外共享路由实例对象
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (About.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import('@/views/AboutView.vue')}]
})export default router
⑤在main.js 中导入并挂载路由模块
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
高级用法
嵌套路由
也可以使用 <router-view> 继续嵌套 <router-view> 实现多层的嵌套视图。
上层routeview 切换到 home与test页面
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/test">test</RouterLink>
<RouterView />{path: '/',name: 'home',component: HomeView,},{path:'/test',name: 'test',component: TestPage,children:[{ path: 'tab1',component: TabView1},{ path: 'tab2',component: TabView2}]},
下层routeview test页面(TestPage) 核心配置: 可以切换到 tab1 tab2页签
<router-link to="/test/tab1" >tab1</router-link>
<router-link to="/test/tab2" >tab2</router-link>
<router-view />
动态路由
动态路由指的是:把Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在vue-router 中使用英文的冒号(:)来定义路由的参数项。示例代码如下:
{ path: 'tab/:id',component: TabView},
现在像 /test/tab/1 和 /test/tab/2 都会映射到同一个组件。
路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 route.params 的形式暴露出来。因此,我们可以通过更新 User 的模板来呈现当前的用户 ID:
<template><div><!-- 当前路由可以通过 $route 在模板中访问 -->this is tab {{ $route.params.id }}</div>
</template>
动态路由参数传递:可以通过设置 props: true 来配置路由将 id 参数作为 prop 传递给组件:
//路由配置
{ path: 'tab/:id',component: TabView, props:true},//页面配置
<template>this is tab: {{id}}
</template>
<script>export default {props:['id']}
</script>
- 路由的匹配规则
https://router.vuejs.org/zh/guide/essentials/route-matching-syntax.html
重定向redirect和别名
重定向
路由重定向指的是:用户在访问地址A 的时候,强制用户跳转到地址C ,从而展示特定的组件页面。通过路由规则的redirect属性,指定一个新的路由地址,可以很方便地设置路由的重定向:
重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /:
在写 redirect 的时候,可以省略 component 配置
<RouterLink to="/test">About</RouterLink>//访问的虽然是/test ,但是会跳转到/about
{path:'/test',name: 'test',redirect:'/about',
},
重定向的目标也可以是一个命名的路由:redirect: { name: 'testpage' }也可以是一个方法,动态返回重定向目标:{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// 方法接收目标路由作为参数
// return 重定向的字符串路径/路径对象
return { path: '/search', query: { q: to.params.searchText } }
},
},
{
path: '/search',
// ...
- redirect: to => { … } 说明
redirect:这是 Vue Router 中路由配置对象中的一个选项,用于指定路由重定向规则。
to:这是一个函数参数,代表目标路由对象,包含了路由的相关信息,比如参数、路径等。
to => { … }:这是一个箭头函数,接收 to 参数,并返回一个对象,用于描述重定向的目标路由。
在你的示例中,当用户访问 /search/:searchText 路由时,会触发重定向到 /search 路由,并将 searchText 参数的值作为查询参数 q 的值传递过去。这样可以实现将动态路径参数转换为查询参数的功能。
相对重定向
{// 将总是把/users/123/posts重定向到/users/123/profile。path: '/users/:id/posts',redirect: to => {// 该函数接收目标路由作为参数// 相对位置不以`/`开头// 或 { path: 'profile'}return 'profile'},},
别名-alias
设置别名意味着多个url 对应一同一个内容
如将 / 别名为 /home,意味着当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 /。
{path: '/users',component: UsersLayout,children: [// 为这 3 个 URL 呈现 UserList// - /users// - /users/list// - /people{ path: '', component: UserList, alias: ['/people', 'list'] },],}
编程式导航
除了使用 <router-link> 创建 a 标签来定义导航链接,还可以借助 router 的实例方法,通过编写代码来实现。
声明式
<router-link :to="...">
编程式:
router.push(...)
将之前的标签触发,改为函数触发
<button @click="goTab(2)" >tab2</button>methods:{goTab(id){this.$router.push("/test/tab/"+id)}}
- 更多用法
https://router.vuejs.org/zh/guide/essentials/navigation.html
导航守卫
vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。
全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。可以按照如下的方式定义全局导航守卫:
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
守卫方法接收参数:
- to: 即将要进入的目标 用一种标准化的方式
- from: 当前导航正要离开的路由 用一种标准化的方式
- next: 新版本当前为可选参数, next是一个函数,通过调用它以验证导航。如果守卫的回调函数中有返回值,则可以省略 next , 如果传递了该参数,请确保它被严格调用一次,否则页面将会卡住,无法顺利跳转或展示数据。
它的执行效果依赖调用时所传递的参数:
next() 不传递参数时,会进行管道中的下一个钩子
next(false) 中断当前的导航
next(‘/otherPath’) 或者 next({ path: ‘/otherPath’ }) 当前的导航被中断,然后进行一个新的导航,跳转到一个不同的地址
传递对象可以定制跳转的方式,如 next({ replace: true, name: ‘home’ }) 以取代历史记录的方式,跳转导航到首页。
next(error) 传入 next 的参数是一个 Error 实例,则导航会被终止
可以返回的值如下
- false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
- 一个路由地址: 通过一个路由地址重定向到一个不同的地址,如同调用 router.push(),且可以传入诸如 replace: true 或 name: ‘home’ 之类的选项。它会中断当前的导航,同时用相同的 from 创建一个新导航。
- 如果返回 true、undefined 或者不返回任何值(即默认返回 undefined),则路由会继续进行,即允许路由跳转。
则导航是有效的,并调用下一个导航守卫
//这里不需要nextrouter.beforeEach(async (to, from) => {if (// 检查用户是否已登录!isAuthenticated &&// ❗️ 避免无限重定向to.name !== 'Login') {// 将用户重定向到登录页面return { name: 'Login' }}})//async这里是异步,意味着在路由修改之前,可以有其他操作比如页面显示元素的变化,不如loading 页面等,可以先操作。
更多相关内容
https://router.vuejs.org/zh/guide/advanced/navigation-guards.html
案例
案例源码
https://github.com/nebofeng/Vue3_demo/tree/master/04-vue-router
用到的知识点
- 嵌套路由、动态路由相关
效果
备注
IT 内容具有时效性,未避免更新后未同步,请点击查看最新内容:Vue3-06_路由
文章首发于:https://nebofeng.com/2024/11/10/vue3-06_%e8%b7%af%e7%94%b1/