在web开发中,"router"是指根据url分配到对应的处理程序html
//vue <script src="https://unpkg.com/vue/dist/vue.js"></script> //vue-router <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
npm install vue-router
在使用Vue.js的时候,咱们经过组合组件来组成应用程序,如今咱们要把vue-router添加进来,只须要将组件(components)映射到路由(routes),而后告诉 vue-router 在哪里渲染它们。vue
<div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 组件来导航. --> <!-- 经过传入 `to` 属性指定连接. --> <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的组件将渲染在这里 --> <router-view></router-view> </div> <script> // 1. 定义(路由)组件。 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定义路由 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 建立 router 实例,而后传 `routes` 配置 const router = new VueRouter({ routes // (缩写)至关于 routes: routes }) // 4. 建立和挂载根实例。 const app = new Vue({ el:'#app', router }) </script>
注意,若是使用模块化编程。就须要导入vue和VueRouter,在js中调用 Vue.use(VueRouter)web
例如,咱们有一个 User 组件,对于全部 ID 各不相同的用户,都要使用这个组件来渲染。那么,咱们能够在 vue-router 的路由路径中使用『动态路径参数』(dynamic segment)来达到这个效果:vue-router
HTMLshell
div id="app"> <h1>Hello App!</h1> <p> <router-link to="/foo">Go to Foo</router-link><br/> <router-link to="/bar">Go to Bar</router-link><br/> <router-link to="/user">user</router-link> </p> <router-view></router-view> </div>
JAVASCRIPTnpm
onst Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } const User = {template:` <div> <h2>user</h2> {{$route.params.name}} </div>` } const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar }, { path:'/user', component:User, children:[ { path:':name'//动态路径参数以冒号开头 } ] } ] const router = new VueRouter({ routes }) const app = new Vue({ el:'#app', router })
借助 vue-router,使用嵌套路由配置,就能够很简单地表达组件中的层级关系编程
实际上,在上面的动态路由的例子中就已经使用了嵌套了,定义路由时添加一个 children 属性便可:数组
const routes=[ { path:'/user', component:User, children:[ { path:':name', component:{ template:'<div>pureview</div>' } } ] } ]
< router-view >标签在模板中会被渲染为一个< a >标签来进行连接,其实,也可使用 "router.push()" 来实现导航浏览器
<div id="app"> <input value="按钮" type="button" v-on:click="btn"> </div> <script> new Vue({ el:'#app', methods:{ btn:function(){ router.push('/user') } } }) </script>
该方法的参数能够是一个字符串路径,或者一个描述地址的对象。例如:app
// 字符串 router.push('home') // 对象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 带查询参数,变成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
跟 router.push 很像,惟一的不一样就是,它不会向 history 添加新记录,而是跟它的方法名同样 —— 替换掉当前的 history 记录。
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,相似 window.history.go(n)。
// 在浏览器记录中前进一步,等同于 history.forward() router.go(1) // 后退一步记录,等同于 history.back() router.go(-1) // 前进 3 步记录 router.go(3) // 若是 history 记录不够用,那就默默地失败呗 router.go(-100) router.go(100)
路由组件是能够进行命名的,在执行连接或者跳转页面时就会比较方便。命名的方式也很简单,给routes一个name属性就OK了
var router=new VueRouter({ routes:[ { path:'/home', name:'homePage', component:Home } ] })
要连接到一个命名路由,能够给 router-link 的 to 属性传一个对象:
<router-link to="{name:'homePage'}">Home</router-link>
有时候想同时(同级)展现多个视图,而不是嵌套展现,例如建立一个布局,有 sidebar(侧导航) 和 main(主内容) 两个视图,这个时候命名视图就派上用场了。你能够在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。若是 router-view 没有设置名字,那么默认为 default。
HTML
<div id="app"> <div> <h2>视图一</h2> <router-view name="one"></router-view> </div> <div> <h2>视图二</h2> <router-view name="two"></router-view> </div> </div>
JAVASCRIPT
var Foo={ template:'<div>内容一</div>' } var Bar={ template:'<div>内容二</div>' } var routes=[ { path:'/', components:{ one:Foo, two:Bar } } ] var router=new VueRouter({ routes })
重定向的意思就是当你访问 a 的时候,url 会被替换为 b ,因而匹配路由 b
重定向也是经过 routes 配置来完成,下面例子是从 /a 重定向到 /b:
var router=new VueRouter({ routes:[ { path:'/a', redirect:'/b' } ] })
意思就是当咱们访问 b 的时候,路由匹配为 a ,可是url地址不变
var router=new VueRouter({ routes:[ { path:'/a', alias:'/b' } ] })
vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。有多种方式能够在路由导航发生时执行钩子:全局的, 单个路由独享的, 或者组件级的。
你可使用 router.beforeEach 注册一个全局的 before 钩子:
router .beforeEach((to,from,next)=>{ //... })
钩子函数的三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 必定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。若是所有钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。若是浏览器的 URL 改变了(多是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: ' / ' }): 跳转到一个不一样的地址。当前的导航被中断,而后进行一个新的导航。
作一个小例子:
作了一个简单的页面,设定了一个登录状态,若是 isLogin 为false,那么点击帐户中心,则跳转到登录页进行登录
若是 isLogin 为true,则显示帐户中心的内容:
钩子函数代码
router.beforeEach((to, from, next) => { var isLogin = true ; if(to.path == "/user"&&!isLogin){ next("/login") }else{ next(); } })
贴上完整代码你们能够直接复制试一试
<div id="app"> <p> <router-link to="/foo">首页</router-link> <router-link to="/bar">关于咱们</router-link> <router-link to="/user">帐户中心</router-link> <router-link to="/login">登陆</router-link> </p> <router-view></router-view> </div> <script> var Foo = { template:"<div>我是首页</div>" } var Bar = { template:"<div>我是关于咱们</div>" } var User = { template:"<div>我是帐户中心</div>" } var Login = { template:"<div>我是登陆</div>" } var routes = [ {path:"/foo" , component:Foo}, {path:"/bar" , component:Bar}, {path:"/user" , component:User}, {path:"/login" , component:Login} ] var router = new VueRouter({ routes }) router.beforeEach((to, from, next) => { var isLogin = true ; if(to.path == "/user"&&!isLogin){ next("/login") }else{ next(); } }) var app = new Vue({ el:"#app", router }); </script>
定义路由的时候能够配置 meta 字段:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, meta: { requiresAuth: true } } ] } ] })
那么如何访问这个 meta 字段呢?
首先,咱们称呼 routes 配置中的每一个路由对象为 路由记录。路由记录能够是嵌套的,所以,当一个路由匹配成功后,他可能匹配多个路由记录。
例如,根据上面的路由配置,/foo/bar 这个 URL 将会匹配父路由记录以及子路由记录。
一个路由匹配到的全部路由记录会暴露为 $route 对象(还有在导航钩子中的 route 对象)的 $route.matched 数组。所以,咱们须要遍历 $route.matched 来检查路由记录中的 meta 字段。
下面例子展现在全局导航钩子中检查 meta 字段:
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { // 此路由须要验证,检查是否登陆 // 若是不须要,则重定向到登陆页面。 if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } else { next() // 确保必定要调用 next() } })