vue路由详解
- 一、路由属性配置说明
- 二、页面跳转
-
- (1)router-link标签跳转
- [(2) 编程式导航 - JS代码内部跳转](#(2) 编程式导航 - JS代码内部跳转)
- (3)其他常用方法
- [三、子路由 - 路由嵌套](#三、子路由 - 路由嵌套)
-
- [(1) src/components/Home.vue(父页面)](#(1) src/components/Home.vue(父页面))
- (2)src/components/One.vue(子页面1)
- (3)src/components/Two.vue(子页面2)
- (4)src/router/index.js(路由配置)
- (5)效果图
- 四、路由传递参数
-
- [(1)通过<router-link> 标签中的to传参](#(1)通过<router-link> 标签中的to传参)
- (2)url中传递参数
- [(3)编程式导航 - params传递参数](#(3)编程式导航 - params传递参数)
- (4)编程式导航-query传递参数
- 五、mode模式
- 六、404页面设置
- 七、路由懒加载
- 八、路由重定向
- 九、路由别名
- 十、路由钩子
本篇文章主要介绍Vue路由的用法,内容几乎涉及实际项目开发中需要用到路由的所有场景,对面正在学习Vue路由的小伙伴看过来~~
一、路由属性配置说明
javascript
export default new Router({
mode: 'history', //路由模式,取值为history与hash
base: '/', //打包路径,默认为/,可以修改
routes: [
{
path: string, //路径
ccomponent: Component; //页面组件
name: string; // 命名路由-路由名称
components: { [name: string]: Component }; // 命名视图组件
redirect: string | Location | Function; // 重定向
props: boolean | string | Function; // 路由组件传递参数
alias: string | Array<string>; // 路由别名
children: Array<RouteConfig>; // 嵌套子路由
beforeEnter?: (to: Route, from: Route, next: Function) => void; // 路由单独钩子
meta: any; // 自定义标签属性,比如:是否需要登录
icon: any; // 图标
// 2.6.0+
caseSensitive: boolean; // 匹配规则是否大小写敏感?(默认值:false)
pathToRegexpOptions: Object; // 编译正则的选项
}
]
})
二、页面跳转
(1)router-link标签跳转
在html标签内使用 router-link 跳转,相应于超链接a标签,使用方式如下:
to:导航路径
html
<router-link to="/">[显示字段]</router-link>
使用示例如下:
html
<p>导航 :
<router-link to="/">首页</router-link>
<router-link to="/hello">hello</router-link>
</p>
(2) 编程式导航 - JS代码内部跳转
实际项目中,很多时候都是通过在JS代码内部进行导航的跳转,使用方式如下:
javascript
this.$router.push('/xxx')
具体的简单用法:
- 先编写一个按钮,在按钮上绑定 goHome( ) 方法。
javascript
<button @click="goHome">回到首页</button>
- 在
javascript
export default {
name: 'app',
methods: {
goHome(){
this.$router.push('/home');
}
}
}
(3)其他常用方法
- this.$router.replace()
javascript
this.$router.replace('/home')
描述:同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。
- this.$router.go(n)
相对于当前页面向前或向后跳转多少个页面,类似 window.history.go(n)。n可为正数可为负数。正数返回上一个页面。
javascript
// 后退一步记录,等同于 history.back()
this.$router.go(-1)
// 在浏览器记录中前进一步,等同于 history.forward()
this.$router.go(1)
三、子路由 - 路由嵌套
子路由,也叫路由嵌套,采用在children后跟路由数组来实现,数组里和其他配置路由基本相同,需要配置path和component,然后在相应部分添加来展现子页面信息,相当于嵌入iframe。具体看下面的示例
(1) src/components/Home.vue(父页面)
html
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<!-- 添加子路由导航 -->
<p>导航 :
<router-link to="/home">首页</router-link> |
<router-link to="/home/one">-子页面1</router-link> |
<router-link to="/home/two">-子页面2</router-link>
</p>
<!-- 子页面展示部分 -->
<router-view/>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
msg: 'Home Page!'
}
}
}
</script>
<style scoped>
</style>
(2)src/components/One.vue(子页面1)
html
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'One',
data () {
return {
msg: 'Hi, I am One Page!'
}
}
}
</script>
<style scoped>
</style>
(3)src/components/Two.vue(子页面2)
html
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'Two',
data () {
return {
msg: 'Hi, I am Two Page!'
}
}
}
</script>
<style scoped>
</style>
(4)src/router/index.js(路由配置)
javascript
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import One from '@/components/One'
import Two from '@/components/Two'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/', // 默认页面重定向到主页
redirect: '/home'
},
{
path: '/home', // 主页路由
name: 'Home',
component: Home,
children:[ // 嵌套子路由
{
path:'one', // 子页面1
component:One
},
{
path:'two', // 子页面2
component:Two
},
]
}
]
})
(5)效果图
四、路由传递参数
(1)通过 标签中的to传参
基本语法:
html
<router-link :to="{name:xxx, params: {key:value}}">valueString</router-link>
PS :上面to前边是带冒号的,后边跟的是一个对象形式的字符串。
- name:在路由配置文件中起的name值。叫做命名路由。
- params:要传的参数,它是对象形式,在对象里可以传递多个值。
具体实例如下:
(1)在src/components/Home.vue里面导航中添加如下代码:
html
<router-link :to="{name: 'one', params:{username:'test123'}}">子页面1</router-link>
(2)在src/router/indes.js中添加如下代码,重点是name:
javascript
{
path:'one', // 子页面1
name: 'one', // 路由名称-命名路由
component:One
}
(3)在src/components/One.vue里面接受参数,代码如下:
html
<h2>{{$route.params.username}}</h2>
(2)url中传递参数
(1)在路由中以冒号传递,在src/router/index.js中加入如下代码:
javascript
{
path:'/home/two/:id/:name', // 子页面2
component:Two
},
(2)接受参数,在src/components/Two.vuez中加入如下代码:
html
<p>ID:{{ $route.params.id}}</p>
<p>名称:{{ $route.params.name}}</p>
(3)路由跳转,在src/components/Home.vue中加入如下代码:
html
<router-link to="/home/two/1/张三">子页面2</router-link>
PS:to前没有冒号为字符串路由,必须全部匹配。
(4)如果路由参数需要有特定的规则,就需要加入正则表达式了,示例如下:
javascript
{
path:'/home/two/:id(\\d+)/:name', // 子页面2
component:Two
}
(3)编程式导航 - params传递参数
(1)在src/router/index.js页面加入如下代码:
javascript
{
path:'/home/three', // 子页面3
name: 'three',
component:Three
}
(2)在src/components/Three.vue页面加入如下代码:
html
<p>ID:{{ $route.params.id}}</p>
<p>名称:{{ $route.params.name}}</p>
(3)在src/components/Home.vue中加入如下代码:
html
// template
<button @click="toThreePage">页面3-params传参</button>
// script
methods: {
toThreePage() {
this.$router.push({name: 'three', params: {id: 1, name: 'zhangsan'}})
}
}
说明:
- 动态路由使用params传递参数,在this.$router.push() 方法中path不能和params一起使用,否则params将无效。需要用name来指定页面。
- 以上方式参数不会显示到浏览器的地址栏中,如果刷新一次页面,就获取不到参数了,改进方式将第一部分中的代码改成如下:
javascript
{
path:'/home/three/:id/:name', // 子页面3
name: 'three',
component:Three
}
(4)编程式导航-query传递参数
(1)在src/router/index.js页面加入如下代码:
javascript
{
path:'/home/three', // 子页面3
name: 'three',
component:Three
}
(2)在src/components/Three.vue页面加入如下代码:
html
<p>ID:{{ $route.params.id}}</p>
<p>名称:{{ $route.params.name}}</p>
(3)在src/components/Home.vue中加入如下代码:
javascript
// template
<button @click="toThreePage">页面3-params传参</button>
// script
methods: {
toThreePage() {
this.$router.push({path: '/home/three', query: {id: 1, name: 'zhangsan'}})
}
}
PS:动态路由使用query传递参数,会显示到浏览器地址栏中,以上链接为
/home/three?id=1&name=zhangsan
五、mode模式
代码示例:
javascript
export default new Router({
mode: 'history', //mode模式
routes: [...]
})
mode取值说明:
- histroy:URL就像正常的 url,示例:http://localhost:8080/home
- hash:默认值,会多一个"#",示例:http://localhost:8080/#/home
六、404页面设置
如果访问的路由不存在,或者用户输入错误时,会有一个404友好的提示页面,配置如下:
(1)在/src/router/index.js中加入如下代码:
javascript
// 404
{
path: '*',
component: () => import('@/components/404')
}
(2)在src/components/404.vue中编写如下代码:
html
<template>
<div class="hello">
<h1>404 not found</h1>
</div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style scoped>
</style>
七、路由懒加载
大项目中,为了提高初始化页面的效率,路由一般使用懒加载模式,一共三种实现方式。
(1)第一种写法:
javascript
component: (resolve) => require(['@/components/One'], resolve)
(2)第二种写法(推荐):
javascript
component: () => import('@/components/Two')
(3)第三种写法:
javascript
components: r => require.ensure([], () => r(require('@/components/Three')), 'group-home')
八、路由重定向
在定义路由的时候,可以通过添加redirect参数,重定向到另外一个页面。
javascript
routes: [{
path: "/",
redirect: "/article"
}]
九、路由别名
在定义路由的时候,可以通过添加alias 参数,表示该url的别名,以后也可以通过这个别名来访问到这个组件。
javascript
let router = new VueRouter({
routes: [ {
path: "/article",
component: article,
alias: "/list"
}]
})
十、路由钩子
路由钩子,即导航钩子,其实就是路由拦截器,vue-router一共有三类:
- 全局钩子:最常用
- 路由单独钩子
- 组件内钩子
1、全局钩子
在src/router/index.js中使用,代码如下:
javascript
// 定义路由配置
const router = new VueRouter({ ... })
// 全局路由拦截-进入页面前执行
router.beforeEach((to, from, next) => {
// 这里可以加入全局登陆判断
// 继续执行
next();
});
// 全局后置钩子-常用于结束动画等
router.afterEach(() => {
//不接受next
});
export default router;
每个钩子方法接收三个参数:
- to: Route : 即将要进入的目标 [路由对象]
- from: Route : 当前导航正要离开的路由
- next: Function : 继续执行函数
- next():继续执行
- next(false):中断当前的导航。
- next('/') 或 next({ path: '/' }):跳转新页面,常用于登陆失效跳转登陆
2、路由单独钩子
使用:在路由配置中单独加入钩子,在src/router/index.js中使用,代码如下:
javascript
{
path:'/home/one', // 子页面1
component: One,
// 路由内钩子
beforeEnter: (to, from, next) => {
console.log('进入前执行');
next();
}
}
3、组件内钩子
使用:在路由组件内定义钩子函数:
- beforeRouteEnter:进入页面前调用
- beforeRouteUpdate (2.2 新增):页面路由改变时调用,一般需要带参数
- beforeRouteLeave :离开页面调用
任意找一页面,编写如下代码:
html
<script>
export default {
name: 'Two',
data () {
return {
msg: 'Hi, I am Two Page!'
}
},
// 进入页面前调用
beforeRouteEnter(to, from, next) {
console.log('进入enter路由钩子')
next()
},
// 离开页面调用
beforeRouteLeave(to,from, next){
console.log('进入leave路由钩子')
next()
},
// 页面路由改变时调用
beforeRouteUpdate(to, from, next) {
console.log('进入update路由钩子')
console.log(to.params.id)
next()
}
}
</script>