Vue路由(vue-router)详细讲解指南-vue路由原理怎么回答

2023-08-07 19:45:27

 

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

1.嵌套的路由/视图表

2.模块化的、基于组件的路由配置

3.路由参数、查询、通配符

4.基于 Vue.js 过渡系统的视图过渡效果

5.细粒度的导航控制

6.带有自动激活的 CSS class 的链接

7.HTML5 历史模式或 hash 模式,在 IE9 中自动降级

8.自定义的滚动条行为

1.安装

NPM

npm install vue-router –save

如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

import Vue from vue

import VueRouter from vue-router

Vue.use(VueRouter)

2.基础

起步

HTML指定路由显示位置

App.vue:<router-view></router-view>

JavaScript配置路由

1. 定义 (路由) 组件

创建了两个组件:Home.vue和About.vue

2. 定义路由

const routes = [ { path:"/", component:Home }, { path:"/about", component:About } ]

3. 创建 router 实例,然后传 `routes` 配置

const router = new VueRouter({ routes })

4. 创建和挂载根实例

new Vue({ render: h => h(App), router }).$mount(#app)

5.增加跳转规则

<li><router-link to="/">首页</router-link></li> <li><router-link to="/about">关于</router-link></li>

动态路由匹配(路由传递参数)

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

定义传递参数的key
{ path: "/user/:username", component: User }
传递参数值
<li><router-link :to="/user/+username">用户</router-link></li>
读取参数
{{ this.$route.params.username }}

捕获所有路由或 404 Not found 路由

{ // 会匹配所有路径 path: * } { // 会匹配以 `/user-` 开头的任意路径 path: /user-* }

嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件

借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

{ path:"/news", component:News, children:[ { // 不需要表现为路径,他会自动补全 path:"sports", component:Sports }, { path:"yule", component:Yule } ] }

对应的子路由需要显示的位置:news ->

<router-view></router-view>

注意事项:

要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。跳转的连接要写全路径<li><router-link to="/news/yule">娱乐</router-link></li>

编程式的导航

除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。

关于<router-link>解释

<router-link> 组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的 <a> 标签,可以通过配置 tag 属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。

<router-link> 比起写死的 <a href="..."> 会好一些,理由如下:

1.无论是 HTML5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须作任何变动。

2.在 HTML5 history 模式下,router-link 会守卫点击事件,让浏览器不再重新加载页面。

3.当你在 HTML5 history 模式下使用 base 选项之后,所有的 to 属性都不需要写 (基路径) 了。

router.push(location, onComplete?, onAbort?) // 字符串 router.push(home) // 对象 router.push({ path: home }) // 命名的路由 router.push({ name: user, params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: register, query: { plan: private }}) router.replace(location, onComplete?, onAbort?)

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录

router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。

命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

const router = new VueRouter({ routes: [ { path: /user/:userId, name: user, component: User } ] }) <router-link :to="{ name: user, params: { userId: 123 }}">User</router-link> router.push({ name: user, params: { userId: 123 }})

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。

<router-view class="view one"></router-view> <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view>

一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

const router = new VueRouter({ routes: [ { path: /, components: { default: Foo, a: Bar, b: Baz } } ] })

重定向和别名

重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b

const router = new VueRouter({ routes: [ { path: /a, redirect: /b } ] })

别名,/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

const router = new VueRouter({ routes: [ { path: /a, component: A, alias: /b } ] })

路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。

使用 props 将组件和路由解耦:

取代与 $route 的耦合

const User = { props: [id], template: <div>User {{ id }}</div> } const router = new VueRouter({ routes: [ { path: /user/:id, component: User, props: true }, // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项: { path: /user/:id, components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ] })

HTML5 History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。

如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

const router = new VueRouter({ mode: history, routes: [...] })

当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!

不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。

导航高亮效果

Router-link默认携带class:router-link-active和router-link-exact-active,可以用来设置样式

当然class过长可以通过全局配置来修改:linkActiveClass和linkExactActiveClass

Exact:精准匹配,主要解决根目录的匹配规则

进阶

导航守卫

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

每个守卫方法接收三个参数:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

next(/) 或者 next({ path: / }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: home 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。

next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保要调用 next 方法,否则钩子就不会被 resolved。

全局解析守卫

在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

router.afterEach((to, from) => { // ... })

路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({ routes: [ { path: /foo, component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })

这些守卫与全局前置守卫的方法参数是一样的。

组件内的守卫

最后,你可以在路由组件内直接定义以下路由导航守卫:

beforeRouteEnter beforeRouteUpdate (2.2 新增) beforeRouteLeave const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }

完整的导航解析流程

1.导航被触发。

2.在失活的组件里调用离开守卫。

3.调用全局的 beforeEach 守卫。

4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。

5.在路由配置里调用 beforeEnter。

6.解析异步路由组件。

7.在被激活的组件里调用 beforeRouteEnter。

8.调用全局的 beforeResolve 守卫 (2.5+)。

9.导航被确认。

10.调用全局的 afterEach 钩子。

11.触发 DOM 更新。

12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

今天的文章就到这里,下篇我们一起来学习Vue路由守卫!!!

加油!!

对应的视频教程点击下方的链接即可观看:


以上就是关于《Vue路由(vue-router)详细讲解指南-vue路由原理怎么回答》的全部内容,本文网址:https://www.7ca.cn/baike/60014.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明

排行榜