之前只是单纯的学习,并未对vue-router做一个系统的总结。所以今天我试着参照官方文档对vue-router的一些常用 API 做一些总结作为日后复习所用。
起步
vue-router的作用就是将组件映射至路由上,以告诉vue-router在哪里渲染他们。相较于原生 vueJS 组件化,vue-router使得变化可以显示到 url 上,更符合大家的编程习惯。
1 | <script src="https://unpkg.com/vue/dist/vue.js"></script> |
1 | // 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter) |
$router?$route
我们可以通过this.$router访问当前路由。也可以通过this.$route访问当前路由对象。那么二者有什么区别呢?
$router是指整个路由实例。你可以操纵整个路由,通过this.$router.push向其中添加任意的路由对象$route是指当前路由实例($router)跳转到的路由对象
通过此 API 我们可以实现一些针对于页面的操作
this.$router.go(num):向前/后跳转页面
this.$router.push('/'):跳转到根路径
动态传参
动态传参一般用于传递动态参数。举个栗子,我们在博客页面在点击详情页时会动态传递一个参数(比如第1篇博客则传入编号为1)。
动态传参有两种形式:params和query
query
query传参有些类似于为后台以字符串形式传参,总之就是一个丑。
我们只需要在.vue文件中定义
1 | // query通过path切换路由 |
params
params传参则是需要在route中以冒号开头定义
1 | const User = { |
而在.vue文件中则是在:to中定义
1 | <router-link :to="{name: 'Detail', params: { id: 1}">详情</router-link> |
区别
path和params无法同时生效,否则params会被忽略掉。所以使用对象写法进行
params传参时,要么就是path加冒号,要么就是像命名路由,通过name和params进行传参。而
query却不受影响,有没有path都可以传参
这俩的区别也显而易见:
丑
一个丑一个好看,这个我不多BB了吧
切换路由的方式
1 | // query通过path切换路由 |
接收参数的方式
看清楚咯老弟!!!这是this.$route!(当前路由实例)不是this.$router(整个路由实例)
1 | // query通过this.$route.query接收参数 |
route/index.js文件
params必须在路由中的index.js文件中定义
1 | <router-link :to="{name: 'Detail', params: { id: 1}">详情</router-link> |
而query传参则不需要
响应路由参数的变化
从/user/foo跳转到/user/bar中时user组件会被复用。这也意味着user组件的生命周期钩子不会再被调用
所以为了解决这种方式我们可以用watch监听$router对象的变化
1 | const User = { |
或者使用 2.2 新增的 API:beforeRouteUpdate(导航守卫)
1 | const User = { |
路由捕获
1 | { |
注意,当我们使用了通配符*后则$route.params会自动添加一个pathMatch参数,它就是*被匹配的部分
编程式导航
router.push(location, onComplete?, onAbort?)
这东西咱们在《$router?$route》部分就提了一嘴。那么我们就来细看一下this.$router.push这个API
1 | router.push(location, onComplete?, onAbort?) |
举几个栗子
1 | // 字符串 |
注意一哈,如果提供了path,那么params则会被忽略。
我们前面讲到了,
query通过path切换路由,而params则通过name切换路由
1 | const userId = '123' |
router.go(n)
在history记录中前进或后退多少步(类似于window.history.go(n))
router.replace(location, onComplete?, onAbort?)
这个除了不会向history中添加新纪录之外和router.push一模一样(替换到当前的history记录)
命名视图&命名路由
这东西,说白了就是俩字儿,好认。
命名路由
命名路由咱们用的比较多,毕竟params是靠name来切换路由的。
1 | routes: [ |
不过注意一点:我们命名路由中的name属性和.vue文件中的name属性是不一样的!!!
给你们举个例子,我自己做的项目,跑跑,你可以去/route/index.js中看一下,为了区分我们将每个路由的name属性前面都加了其相应的权限(windowAdmin、admin、superAdmin),而在对应的组件(component)中没有一个和他们的name是一样的。但依然解决了报错问题。
项目地址今后我完成后会贴在这里。
params切换路由?
众所周知params传参是根据name属性进行路由切换的,而此name属性就是命名路由中的name。
诸位好汉别写成.vue文件中的name了哦。
命名视图
而命名视图则是给我们的<router-view>起一个名字(name属性)。当一个路由需要匹配多个组件时就需要带上name属性咯
1 | <router-view class="view one"></router-view> |
1 | const router = new VueRouter({ |
提一嘴就够
重定向
只要匹配到相应的路径,那么我们就从此路径重定向至另一个路径。一般结合*使用,将乱七八糟的网页重定向到主页上。
1 | const router = new VueRouter({ |
当然重定向的目标也可以是一个命名路由,甚至是一个方法
1 | // 目标为命名路由 |
别名
/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
1 | const router = new VueRouter({ |
路由组件传参
上面我们说到了params和query。不过这玩意儿本质上都是把参数放在 URL 上,通过改变 URL 进行的。如此即会造成参数和组件的高度耦合
而如果使用propos则可以摆脱 URL 的束缚(不改变 URL),提高组件的复用性。
1 | //路由配置: |
而在 HTML 中则正常使用组件即可。所有的逻辑传参部分全部在我们的路由设置(router/index.js)中完成,HTML(.vue)中无需做任何处理,并且也不会改变 URL。
比如这串代码:
1 | const User = { |
通过props解耦后效果如下
1 | const User = { |
HTML5 History模式
开发时我们默认使用hash模式,以此来避免页面的重新加载,使得开发效率更高。
而history模式则是,只要 URL 发生更改都会向服务器发送请求,以此来实时刷新数据。
1 | const router = new VueRouter({ |
重点小结
$router代表整个路由实例,$route则代表当前路由实例<router-link :to="{ }">等同于this.$router.push()path和params是不能同时存在的params参数都不会显示在 URL 地址栏中,除了在路由中通过routes进行配置的。所以用户刷新页面后params参数就会丢失query参数不依赖于route,故刷新页面后亦会存在于地址栏中
路由组建传参中的函数模式可以让传递参数更加灵活,适用于需要逻辑控制的项目。