1 简介及安装
简介
vue-router是一个vue框架的路由管理包。
与ng的路由基本差不多,总体来说只需要记住两个标签<router-link>
(路由导航)和<router-view>
(路由插座)两个元素,然后逐渐扩展。
安装
1. 直接下载/cdn方式,需先引入vue.js再引入vue-router.js
2. npm:npm i vue-router --save-dev
。
2 创建及配置路由
//index.js
import Vue from 'vue';
import Router from 'vue-router';
import Foo from '/component/Foo'
import Bar from '/component/Bar'
Vue.use(Router);
export default new Router({
routes:[
{
path: '/foo',
component: Foo,
},
{
path: '/bar',
component: Foo
}
]
})
在根组件中配置:
//script
import router from './index'
export default {
//...
router,
//...
}
完成上述配置,就可以在模版中使用<router-link>
标签来使用路由了,该标签会被渲染成<a>
标签。
<router-link to="/foo">go to Foo</router-link>
<router-link to="/bar">go to Bar</router-link>
<!-- 也可以直接使用a元素,给v-link指令赋值 -->
<a v-link="{path: '/foo'}>跳转至foo</a>"
<!-- 路由插座 -->
<router-view></router-view>
3 动态路由配置( : id )
对于可复用的组件我们要根据不同数据展示不同的内容,如展示用户信息的面板,可以在vue-router路由路径中使用动态路由参数来实现:
routes: [
{ path: '/user/:id', component: User}
]
当匹配到一个路由时,参数值会被设置到this.$route.params
中,以在组件中使用。
上述情况组件会被复用,也就不会触发组件的生命周期钩子,我们可以用watcher观察$route对象来解决这个问题。
watch:{
'$route' (to,from){
//...
}
}
4 编程式导航
除了使用<router-link>
创建a标签来定义导航链接,还可以借助router的实例方法通过代码来导航。
router.push(location) window.history.pushState
1. 此方法即<router-link to="...">
的内部实现。
2. 通过push方法导航至不同的URL,此方法会向history栈添加新的记录,回退按钮可正常使用。
参数形式:
1. 字符串:router.push(‘home’)
2. 对象:router.push({ path: ‘home’ })
3. 命名的路由:router.push({ name: ‘user’, params: { userId: 123 }})
4. 带查询参数,/register?plan=private:router.push({ path: ‘register’, query: { plan: ‘private’ }})
router.replace(location) window.history.replaceState
此方法与push方法很像,不过是替换,history不能正常使用。
router.go(n) window.history.go
前进或后退n步。
5 HTML History模式
vue-router默认hash模式,可选history模式,比较直观好看。如http://yoursite.com/user/id
不过这种模式容易搞出事情,容易返回404,就比如我现在架设在云虚拟主机上的ng2项目一样。
所以要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
下面看例子:
Apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
Node.js (Express)
https://github.com/bripkens/connect-history-api-fallback
6 路由配置demo
<router-view></router-view>
<!-- 同级路由,通过name属性指定组件 -->
<router-view name="a"></router-view>
<router-view name="b"></router-view>
const router = new Router({
//路由模式,默认hash,可选history
mode: 'history'
routes:[
//重定向
{
path: '/a',
redirect: '/b' //或{ name: 'user'};或方法 to => {...}
},
//别名
//用户访问/b时,URL保持为/b,但路由匹配为/a
{
path: '/a',
component: A,
alias: '/b'
},
{
path: '/user:id',
//为路由定义name,方便导航,{name:'user',params:{...}}
name: 'user',
component: {
default: User,
a:Bar,
b:Baz
},
//子路由
children: [
{ path:'', component:A },
{ path:'b', component:B },
]
}
]
})
7 导航钩子
vue-router的导航钩子与ng2的路由守卫相似,都是在导航过程中挂拦截
导航钩子方法参数:
1. to: Route:即将要进入的目标路由对象。
2. from: Route:当前导航正要离开的路由。
3. next: Function:一定要调用此方法来resolve这个钩子,执行效果依赖next方法的参数:
- next():进行管道中下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed(确认的)。
- next(false):中断当前导航。
- next(‘/’)或next({path:’/’}):跳转到一个不同的地址,当前导航被中断,然后进行一个新的导航。
确保要调用next方法,否则钩子不会被resolved
导航钩子按挂接位置可分为三类:
1. 全局钩子:全局router实例对象的钩子,
- router.beforeEach(to, from, next):跳转前。
- router.afterEach(to, from, next):跳转后。
- 一个导航触发时,全局before钩子按顺序调用,钩子是异步解析执行,导航在所有钩子resolve完之前一直处于等待中。
2. 某个路由独享钩子
- 在路由选项中配置:beforeEnter(to, from, next)。
3. 组件内钩子
- beforeRouteEnter(to, from, next):不能获取组件实例this,此时组件实例还没有被创建。
- 可使用next(vm =>{ //通过回调可访问vm})
- beforeRouteUpdate(to, from, next):当前路由改变但该组件被复用时调用(/:id)。可访问this
- beforeRouteLeave(to, from, next):导航离开该组件的对应路由时调用,可访问this。