一、 基本用法
1、安装
npm install vue-router --save
2、创建组件Home、About
<template>
<div style="background-color: brown;">
<h1>Home</h1>
</div>
</template>
<script>
export default {
name: 'Home',
data () {
return {
}
}
}
</script>
About(只贴了主体部分)
<div style="background-color: cadetblue;">
<h1>About</h1>
</div>
3、引入插件、配置路由
下面的操作总结为一句话就是:将组件(components)映射到路由(routes)
src/router/router.js
import Vue from 'vue'
//0.引入插件vue-router
import Router from 'vue-router'
Vue.use(Router)//使用插件
//1.引入路由组件
import Home from '@/components/Home'
import About from '@/components/About'
// 2. 定义路由
const routes: [//配置路由数组
{//配置链接对象,每个对象就是一条路由,每个路由应该映射一个组件
path: '/home',//链接的路径,这个名字是自己指定的
name: 'Home',//路由的名字,自己指定,用不到也可不写这一项
component: Home//路径对应的组件名称,跟上面import的的组件名称保持一致,component可以是通过 Vue.extend() 创建的组件构造器。
},
{
path: '/about',
name: 'About',
component: About
}
]
//3. 创建 router 实例 router
export const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
4、把路由挂载到根实例
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
// 4. 挂载到根实例
new Vue({
el: '#app',
router,//挂载
components: { App },
template: '<App/>'
})
5、在页面中使用路由
App.vue
<template>
<div id="app">
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
<!-- 路由出口,路由匹配到的组件将渲染在这里 -->
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
这是首页。请注意看每张图片的地址栏
点击Home
点击About
以上,一个简单的路由切换两个页面就实现了。根据上面的实例,相信你已经对路由有了一个初步的认识。
二、Router 实例构建选项
1、http://localhost:8080/#/
中为什么会有 #
?
//3. 创建 router 实例 router
export const router = new VueRouter({
mode:'hash',//默认模式是hash模式,所以地址中有#,http://localhost:8080/#/,当 URL 改变时,页面不会重新加载。
//mode:'hash',//模式设置history模式,去掉#就可以访问:http://localhost:8080/
routes
})
2、指定默认主页
如果想为页面一开始指定一个默认主页Home,可以这么写
export default new Router({
routes: [
{
path: '/',//根路径
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
})
<router-link to="/">Home</router-link>
或者重定向根路径path:/ 到/home
3、 重定向
{
path: '/',
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: Home,
}
1、什么是重定向?
比如有条路径path:/a,它指向路径/a,可以通过重定向操作让这条路径指向/b。
2、为什么要重定向?
当一个路由出现问题的时候,会自动重定向到另外一个路由上去,保证你的数据畅通。
举个栗子:
<div id="app">
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
<router-link to="/fabgoawogn">不存在路径</router-link>
<router-view/>
</div>
/fabgoawogn是随便输入的路径,当我点击它时候,页面上啥都没有,用户体验不太好。
如果给它配置重定向
export default new Router({
routes: [
{
path: '/home',
name: 'Home',
component: Home
},
{
path: '/error',
name: 'Error',
component: Error
},
{
path: '*',// /fabgoawogn无法匹配上面的任何一条路径,匹配到此处
redirect: '/error' //重定向到路径/error 错误提示页面
}
]
})
1、含有通配符的路由应该放在最后。
2、路由 { 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'
点击不存在的路径,页面重定向到了home页面。
(注意看,址栏的路径也变成了/home)
重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
routes: [
{
path: '/a',
redirect: { name: 'foo' }
}
]
})
甚至是一个方法,动态返回重定向目标:
const router = new VueRouter({
routes: [
{
path: '/a',
redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}
}
]
})
4、 路由别名
给路径path:/home起一个别名/welcome
{
path: '/home',
name: 'Home',
component: Home,
alias:'/welcome'//别名
}
<router-link to="/welcome">Welcome</router-link>
可以看到,点击/welcome时,跳转到了/home页,与重定向不同的是,地址栏的路径仍然是/welcome。
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。
注意:别名alias在path:’/'这条路径中,是不起作用的。
二、 动态路由传参
开发中经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,可以在 vue-router 的路由路径中使用动态路径参数来达到这个效果。
给User组件传值 name、age
to
表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。我们就是通过这个值进行传值的。
当 to
的值是字符串:
方法1
<!-- localhost:8080/#/user/张三/24-->
<router-link to="/user/张三/24">张三</router-link>
方法2
<!-- localhost:8080/#/user?name=李四&age=28 -->
<router-link to='/user?name=李四&age=28'>李四</router-link>
当 to
的值是对象:
方法3:通过命名路由
<!-- localhost:8080/#/user/张三/24-->
<router-link :to="{name:'user',params:{name:'张三',age:'24'}}">张三</router-link>
方法4:带查询参数
<!-- localhost:8080/#/user?name=李四&age=28 -->
<router-link :to="{name:'user',query:{name:'李四',age:28}}">李四</router-link>
方法1、3
{
//一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params。
path: '/user/:name/:age',
name: 'User',
component: User
}
<div style="background-color: rgb(139, 202, 243);">
<h1>User</h1>
<!-- $route.params.参数名 获取参数 -->
<h2>我是:{{$route.params.name}}</h2>
<h2>我今年:{{$route.params.age}}岁了</h2>
</div>
在URL中使用正则表达式
{
path: '/user/:id(\\d+)/:name/:age',//校验id是数字
name: 'User',
component: User
}
方法2、4
{
path: '/user',
name: 'User',
component: User,
}
<div style="background-color: rgb(139, 202, 243);">
<h1>User</h1>
<!-- 使用 this.$route.query 来获取路由参数 -->
<h2>我是:{{$route.query.name}}</h2>
<h2>我今年:{{$route.query.age}}岁了</h2>
</div>
三、编程式导航
用第二部分 Router 实例方法的可以实现编程式导航。
1、router.push()
动态导航到不同的URL,向 history 栈添加一个新的记录(新的URL)
这样导航是声明式导航:
<router-link to="/home">Home</router-link>
等同于
router.push('/home')
当 <router-link :to="">
被点击后,内部会立刻把 to
的值传到 router.push(),
所以 router.push()
的值,和to
值一样,可以是一个字符串或者是描述目标位置的对象。
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
注意:如果提供了 path,params 会被忽略。
2、router.replace()
动态导航到不同的URL,不会向 history 栈添加一个新的记录,而是用新的URL替换掉当前的 history 记录。
<router-link to="/home" replace>Home</router-link>
等同于
router.replace('/home')
用法跟 router.push 很像。
3、router.go(n)
在 history 记录中向前或者后退多少步。n取整数。
// 在浏览器记录中前进一步,等同于 history.forward()
router.go(1)
// 后退一步记录,等同于 history.back()
router.go(-1)
// 前进 3 步记录
router.go(3)
// 如果 history 记录不够用,那就默默地失败呗
router.go(-100)
router.go(100)
四、响应路由参数的变化
1、watch监听路由对象$route
当使用路由参数时,例如从 /user/张三导航到 /user/李四,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch 监测 $route 路由对象:
User组件
watch: {
'$route'(to,from){
console.log(to)
console.log(from)
}
}
或者使用 2.2 中引入的 beforeRouteUpdate 导航守卫:
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
点击张三,再点击李四,查看输出:
2、导航钩子函数
直接看官网的例子,写的很详细。vue-router
beforeRouteUpdate(to,from,next){
console.log(to)
console.log(from)
console.log(next)
next();
//next(false); 如果给next传值为false,那就不会跳转。
},
点击张三,再点击李四,查看输出。
五、 子路由(嵌套路由)
<router-link to="/user/张三">张三</router-link>
{
path: '/user/:name',
name: 'User',
component: User,
children: [//子路由
{
path:'more',//主路由上的path会被自动添加到子路由之前,所以此处不用写主路由上的path了。以 / 开头的嵌套路径会被当作根路径。
name:'More',//子路由的名字
component: More//子路由映射的组件
}
]
}
User组件
<div style="background-color: rgb(224, 238, 145);">
<h1>More</h1>
<h2>用户{{$route.params.name}}的详细信息</h2>
</div>
User组件
<div style="background-color: rgb(139, 202, 243);">
<h1>User</h1>
<h2>我是:{{$route.params.name}}</h2>
<router-link :to="'/user/' + $route.params.name +'/more'">更多信息</router-link>
<!-- More会被渲染在 User的 <router-view> 中 -->
<router-view></router-view>
</div>
router-link还可以这么写
<router-link to="more" append>更多信息</router-link>
或者这么写(name是子路由的名字)
<router-link :to="{name:'More'}">更多信息</router-link>
点击更多信息
六、 命名视图
有时候想在界面中同时(同级)展示多个视图,而不是嵌套展示,就用到了命名视图。
<div id="app">
<router-link to="/home">Home</router-link>
<router-link to="/about">About</router-link>
<!-- 如果 router-view 没有设置名字,那么默认为 default -->
<router-view></router-view>
<!-- 下面两个是命名视图 -->
<router-view name="TopBar"></router-view>
<router-view name="Content"></router-view>
</div>
{
path: '/about',
name: 'About',
components: {//一个路由有两个视图,对应了两个组件TopBar和Content,注意components是复数
TopBar,
Content
}
},
组件TopBar
<div style="background-color: rgb(247, 161, 208);">
<h1>TopBar</h1>
</div>
组件Content
<div style="background-color: rgb(167, 240, 72);">
<h1>Content</h1>
</div>
点击About