关于Vue Router的10条高级技巧总结


Posted in Vue.js onMay 06, 2021

前言

Vue Router 是 Vue.js 官方的路由管理器。

它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

包含的功能有:

  • 嵌套的路由/视图表
  • 模块化的、基于组件的路由配置
  • 路由参数、查询、通配符
  • 基于 Vue.js 过渡系统的视图过渡效果
  • 细粒度的导航控制
  • 带有自动激活的 CSS class 的链接
  • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
  • 自定义的滚动条行为

本文是作者是实际项目中遇到的一些总结,主要包括:

  1. 响应路由参数变化
  2. 路由匹配
  3. 高级匹配模式
  4. 匹配优先级
  5. push和replace的第二个第三个参数
  6. 路由视图
  7. 重定向
  8. 使用props解耦$route
  9. 导航守卫
  10. 守卫的next方法

希望本文对你有所帮助。

正文

1. 响应路由参数变化

针对复用组件(只是路由参数发生改变),生命周期函数钩子不会被调用,如何能刷新组件了?

watch监听

watch: {
  '$route' (to, from) {
  // 对路由变化作出响应...
  }
}

beforeRouteUpdate

beforeRouteUpdate (to, from, next) {
// react to route changes...
/ / don't forget to call next()
}

2. 路由匹配

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

注意:当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: '*' } 通常用于客户端 404 错误。

如果你使用了History 模式,请确保正确配置你的服务器。

当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。

它包含了 URL 通过通配符被匹配的部分:

// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'

3. 高级匹配模式

// 命名参数必须有"单个字符"[A-Za-z09]组成
 
// ?可选参数
{ path: '/optional-params/:foo?' }
// 路由跳转是可以设置或者不设置foo参数,可选
<router-link to="/optional-params">/optional-params</router-link>
<router-link to="/optional-params/foo">/optional-params/foo</router-link>
 
// 零个或多个参数
{ path: '/optional-params/*' }
<router-link to="/number">没有参数</router-link>
<router-link to="/number/foo000">一个参数</router-link>
<router-link to="/number/foo111/fff222">多个参数</router-link>
 
 
// 一个或多个参数
{ path: '/optional-params/:foo+' }
<router-link to="/number/foo">一个参数</router-link>
<router-link to="/number/foo/foo111/fff222">多个参数</router-link>
 
// 自定义匹配参数
// 可以为所有参数提供一个自定义的regexp,它将覆盖默认值([^\/]+)
{ path: '/optional-params/:id(\\d+)' }
{ path: '/optional-params/(foo/)?bar' }

4. 匹配优先级

有时候一个路径可能匹配多个路由。

此时,匹配的优先级就是按照路由的定义顺序:先定义,优先级最高。

5. push和replace的第二个第三个参数

在 2.2.0+版本,可选的在 router.push 或 router.replace 中提供 onComplete 和 onAbort 回调作为第二个和第三个参数。

这些回调将会在导航成功完成 (在所有的异步钩子被解析之后) 或终止 (导航到相同的路由、或在当前导航完成之前导航到另一个不同的路由) 的时候进行相应的调用。在 3.1.0+,可以省略第二个和第三个参数,此时如果支持 Promise,router.push 或 router.replace 将返回一个 Promise。

接下来看几个例子来看看第二个第三个参数的调用时机:

1. 组件1跳转组件2

// 组件1
this.$router.push({ name: 'number' }, () => {
  console.log('组件1:onComplete回调');
}, () => {
  console.log('组件1:onAbort回调');
});
// 组件2
beforeRouteEnter(to, from, next) {
  console.log('组件2:beforeRouteEnter');
  next();
},
beforeCreate() {
  console.log('组件2:beforeCreate');
},
created() {
  console.log('组件2:created');
}

关于Vue Router的10条高级技巧总结

组件之间跳转触发onComplete回调。

2. 组件2跳转组件2(不带参数)

this.$router.push({ name: 'number'}, () => {
  console.log('组件2:onComplete回调');
}, () => {
  console.log('组件2,自我跳转:onAbort回调');
});

关于Vue Router的10条高级技巧总结

组件自我跳转当不带参数时触发onAbort回调。但是当自我跳转带参数时可能情况就有点不一样。

3. 组件2跳转组件2(带参数)

this.$router.push({ name: 'number', params: { foo: this.number}}, () => {
    console.log('组件2:onComplete回调');
}, () => {
    console.log('组件2,自我跳转:onAbort回调');
});

关于Vue Router的10条高级技巧总结

组件自我带参数跳转,onComplete回调、onAbort回调回调都不会触发。

6. 路由视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 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
    }
    }
  ]
});

7. 重定向

{ path: '/a', redirect: '/b' }
{ path: '/a', redirect: { name: 'foo' }}
{ path: '/a', redirect: to => {
  // 方法接收 目标路由 作为参数
  // return 重定向的 字符串路径/路径对象
}}

注意:导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上。

在上面这个例子中,为 /a 路由添加一个 beforeEach 或 beforeLeave 守卫并不会有任何效果。

8. 使用props解耦$route

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

// router文件
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
  path: '/number/:name',
  props: true,
  // 对象模式 props: { newsletterPopup: false }
  // 函数模式 props: (route) => ({ query: route.parmas.name })
  name: 'number',
  component: () => import( /* webpackChunkName: "number" */ './views/Number.vue')
}
// 组件获取
export default{
  props: ['name']
}

9. 导航守卫

1. 三种全局守卫

router.beforeEach 全局前置守卫 进入路由之前。

router.beforeResolve 全局解析守卫2.5.0新增。在beforeRouteEnter调用之后调用。

router.afterEach 全局后置钩子 进入路由之后。

// 入口文件
import router from './router'
 
// 全局前置守卫
router.beforeEach((to, from, next) => {
console.log('beforeEach 全局前置守卫');
next();
});
// 全局解析守卫
router.beforeResolve((to, from, next) => {
console.log('beforeResolve 全局解析守卫');
next();
});
// 全局后置守卫
router.afterEach((to, from) => {
console.log('afterEach 全局后置守卫');
});

2. 路由独享守卫

beforeEnter全局前置守卫进入路由之前。

{
  path: '/number/:name',
  props: true,
  name: 'number',
  // 路由独享守卫
  beforeEnter: (to, from, next) => {
      console.log('beforeEnter 路由独享守卫');
      next();
  },
  component: () => import( /* webpackChunkName: "number" */ './views/Number.vue')
}

关于Vue Router的10条高级技巧总结

3. 组件内守卫

beforeRouteEnter

beforeRouteUpdate(2.2新增)

beforeRouteLeave

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

组件1跳转到组件2,然后组件2跳转组件2本身

关于Vue Router的10条高级技巧总结

组件1跳转到组件2,然后组件2跳转组件1

关于Vue Router的10条高级技巧总结

10. 守卫的 next 方法

next: 调用该方法 resolve 钩子。

  • 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() 注册过的回调。

最后

最终还是希望大家多看看文档,理解了再去使用到项目中,不至于使用之后出现 bug,谢谢。

到此这篇关于关于Vue Router的10条高级技巧的文章就介绍到这了,更多相关Vue Router高级技巧内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
Vue实现购物小球抛物线的方法实例
Nov 22 Vue.js
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 Vue.js
vue中如何添加百度统计代码
Dec 19 Vue.js
vue调用微信JSDK 扫一扫,相册等需要注意的事项
Jan 03 Vue.js
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
Feb 26 Vue.js
vue实现桌面向网页拖动文件的示例代码(可显示图片/音频/视频)
Mar 01 Vue.js
vue项目两种方式实现竖向表格的思路分析
Apr 28 Vue.js
vue实现同时设置多个倒计时
May 20 Vue.js
vue中的可拖拽宽度div的实现示例
Apr 08 Vue.js
vue封装数字翻牌器
Apr 20 Vue.js
vue3.0 数字翻牌组件的使用方法详解
Apr 20 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 Vue.js
Vue项目中如何封装axios(统一管理http请求)
May 02 #Vue.js
使用vue-element-admin框架从后端动态获取菜单功能的实现
vue使用v-model进行跨组件绑定的基本实现方法
关于vue中如何监听数组变化
vue实现简单数据双向绑定
Apr 28 #Vue.js
vue引入Excel表格插件的方法
Apr 28 #Vue.js
原生JS封装vue Tab切换效果
You might like
PHP在字符串中查找指定字符串并删除的代码
2008/10/02 PHP
PHP array操作10个小技巧分享
2011/06/23 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
2011/12/05 PHP
Zend Studio 实用快捷键一览表(精心整理)
2013/08/10 PHP
有效的捕获JavaScript焦点的方法小结
2009/10/08 Javascript
DWZ table的原生分页浅谈
2013/03/01 Javascript
js onclick事件传参讲解
2013/11/06 Javascript
jquery select 设置默认选中的示例代码
2014/02/07 Javascript
基于JavaScript实现全选、不选和反选效果
2017/02/15 Javascript
jQuery中clone()函数实现表单中增加和减少输入项
2017/05/13 jQuery
使用JS动态显示文本
2017/09/09 Javascript
使用svg实现动态时钟效果
2018/07/17 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
js实现导航跟随效果
2018/11/17 Javascript
微信小程序获取用户信息的两种方法wx.getUserInfo与open-data实例分析
2019/05/03 Javascript
Angular 2使用路由自定义弹出组件toast操作示例
2019/05/10 Javascript
ant-design-vue 实现表格内部字段验证功能
2019/12/16 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
Vue 401配合Vuex防止多次弹框的案例
2020/11/11 Javascript
[03:42]2016国际邀请赛中国区预选赛首日现场玩家采访
2016/06/26 DOTA
[01:01:43]EG vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
python cx_Oracle模块的安装和使用详细介绍
2017/02/13 Python
Django stark组件使用及原理详解
2019/08/22 Python
css3遮罩层镂空效果的多种实现方法
2020/05/11 HTML / CSS
Mankind美国/加拿大:英国领先的男士美容护发用品公司
2018/12/05 全球购物
城市规划毕业生求职信
2013/10/10 职场文书
优秀毕业生推荐信
2013/11/02 职场文书
2015年城管执法工作总结
2015/07/23 职场文书
2015年国庆节演讲稿范文
2015/07/30 职场文书
防溺水安全教育主题班会
2015/08/12 职场文书
三好学生主要事迹怎么写
2015/11/03 职场文书
小学班主任心得体会
2016/01/07 职场文书
2016年学校安全教育月活动总结
2016/04/06 职场文书
如何判断pytorch是否支持GPU加速
2021/06/01 Python
Redis 彻底禁用RDB持久化操作
2021/07/09 Redis
在windows server 2012 r2中安装mysql的详细步骤
2022/07/23 Servers