首先安装cnpm和vue-router
# 安装cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 安装vue-router
cnpm install vue-router --save-dev
修改src/router/index.js文件(如果没有就新建一个)
import Vue from 'vue' //引入Vue
import Router from 'vue-router' //引入vue-router
Vue.use(Router) //Vue全局使用Router
export default new Router({
routes: [ //配置路由,这里是个数组
{ //每一个链接都是一个对象
path: '/', //链接路径
name: 'Hello', //路由名称,
component: () => import('@/components/Hello') //对应的组件模板
}
]
})
嵌套路由
要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置,如:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
//当你访问 /user/foo 时,User 的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。如果你想要渲染点什么,可以提供一个 空的 子路由:
// 当 /user/:id 匹配成功,
// UserHome 会被渲染在 User 的 <router-view> 中
path: '', component: UserHome
},
{
// 当 /user/:id/profile 匹配成功,
// UserProfile 会被渲染在 User 的 <router-view> 中
path: 'profile',
component: UserProfile
},
{
// 当 /user/:id/posts 匹配成功
// UserPosts 会被渲染在 User 的 <router-view> 中
path: 'posts',
component: UserPosts
}
]
}
]
})
要注意,以 / 开头的嵌套路径会被当作根路径。
参数传递
<!-- 字符串 -->
<router-link to="home">Home</router-link>
<!-- 渲染结果 -->
<a href="home">Home</a>
<!-- 使用 v-bind 的 JS 表达式 -->
<router-link v-bind:to="'home'">Home</router-link>
<!-- 不写 v-bind 也可以,就像绑定别的属性一样 -->
<router-link :to="'home'">Home</router-link>
<!-- 同上 -->
<router-link :to="{ path: 'home' }">Home</router-link>
<!-- 命名的路由 -->
<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>
<!-- 通过$route.params.key来获取-->
<!-- 带查询参数,下面的结果为 /xxx?key=value -->
<router-link :to="{path:xxx,query:{key:value}}">valueString</router-link>
<!-- 通过$route.query.key来获取-->
params 与 query的区别
写法大致相同,在第一部配置的时候params用的是name、query用的是path!
query要用path来引入,params要用name来引入。
注意接收参数的时候,是route而不是router了!
query更加类似于我们ajax中get传参,params则类似于post
vue-router 利用url传递参数
在实际开发也是有很多用URL传值的需求,比如我们在新闻列表中有很多新闻标题整齐的排列,我们需要点击每个新闻标题打开不同的新闻内容,这时在跳转路由时跟上新闻编号就十分实用。
<!-- 在/src/router/index.js文件里配置路由 -->
{
path:'/params/:newsId/:newsTitle',
component:Params
}
<!-- 加入我们的<router-view>标签。这时候我们可以直接利用url传值了 -->
<router-link to="/params/198/jspang website is very good">params</router-link>
正则表达式在URL传值中的应用
上边的例子,我们传递了新闻编号,现在需求升级了,我们希望我们传递的新闻ID只能是数字的形式,这时候我们就需要在传递时有个基本的类型判断,vue是支持正则的。
<!-- 加入正则需要在路由配置文件里(/src/router/index.js)以圆括号的形式加入 -->
path:'/params/:newsId(\\d+)/:newsTitle',
加入了正则,我们再传递数字之外的其他参数,params.vue组件就没有办法接收到
响应路由参数的变化
当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象:
const User = {
template: '...',
watch: {
'$route' (to, from) {
// 对路由变化作出响应...
}
}
}
编程式的导航
1. router.push(location, onComplete?, onAbort?)
注意:在 Vue 实例内部,你可以通过 router.push。
// 字符串
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 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:
const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
同样的规则也适用于 router-link 组件的 to 属性。
2. router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
3. router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
路由的过渡动画
想让路由有过渡动画,需要在<router-view>标签的外部添加<transition>标签
<transition name="fade">
<router-view ></router-view>
</transition>
组件过渡过程中,会有四个CSS类名进行切换,这四个类名与transition的name属性有关;
fade-enter-active和fade-leave-active在整个进入或离开过程中都有效,所以CSS的transition属性在这两个类下进行设置;
比如name=”fade”,会有如下四个CSS类名:
fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除。
fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除。
fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除。
fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除。
.fade-enter {
opacity:0;
}
.fade-leave{
opacity:1;
}
.fade-enter-active{
transition:opacity .5s;
}
.fade-leave-active{
opacity:0;
transition:opacity .5s;
}
404页面的处理
设置我们的路由配置文件(/src/router/index.js)
{
path:'*',
component:() => import('Error')
}
这里的path:’*’就是找不到页面时的配置
路由钩子函数
全局钩子
router.beforeEach((to, from, next) => {
console.log('beforeEach');
});
router.afterEach((to, from) => {
console.log('beforeEach');
});
to,from,next 这三个参数:
to和from是将要进入和将要离开的路由对象,路由对象指的是平时通过this.$route获取到的路由对象。
next:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)。
next() 进入该路由。
next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。
next 跳转新路由,当前的导航被中断,重新开始一个新的导航。
我们可以这样跳转:next('path地址')或者next({path:''})或者next({name:''})
且允许设置诸如 replace: true、name: 'home' 之类的选项
以及你用在router-link或router.push的对象选项。
单个路由钩子
const router = new VueRouter({
routes: [{
path: '/index',
component: index,
beforeEnter(to, from, next) {},
beforeLeave(to, from, next) {}
}]
});
组件钩子
beforeRouteEnter (to, from, next) {
// 在路由独享守卫后调用 不!能!获取组件实例 `this`,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this`
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,可以访问组件实例 `this`
}
beforeRouteEnter访问this
beforeRouteEnter (to, from, next) {
console.log('在路由独享守卫后调用');
next(vm => {
// 通过 `vm` 访问组件实例`this` 执行回调的时机在mounted后面,
})
}
beforeRouteLeave:导航离开该组件的对应路由时调用,我们用它来禁止用户离开,比如还未保存草稿,或者在用户离开前,将setInterval销毁,防止离开之后,定时器还在调用。
beforeRouteLeave (to, from , next) {
if (文章保存) {
next();
// 允许离开或者可以跳到别的路由
} else {
next(false);
// 取消离开
}
}