之前只是单纯的学习,并未对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
,故刷新页面后亦会存在于地址栏中
路由组建传参中的函数模式可以让传递参数更加灵活,适用于需要逻辑控制的项目。