前端最基础的就是 HTML+CSS+Javascript
。掌握了这三门技术就算入门,但也仅仅是入门,如今前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS
),本着提高技术水平,打牢基础知识的中心思想,咱们开课啦(每周四)。html
单页应用的话,咱们主要仍是要依赖 Vue-router 来实现路由系统。今天咱们来看看 vue-router 平常使用的内容。前端
以前咱们有一些系统是用 vue-element-admin 来作的,做者写的不错,路由权限、动态路由权限都有现成的方案。找实现方法能够直接看一下开源的代码。vue
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:webpack
<router-view>
嵌套,而后定义 routes
时定义 children
路由参数、查询、通配符git
/user/:id
,获取的时候this.$route.params.id
*
:通常是在 router 最后定义,指向一个 404 显示$route.query
,也能够获取锚点 $route.hash
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <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> // 0. 若是使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter) // 1. 定义 (路由) 组件。 // 能够从其余文件 import 进来 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定义路由 // 每一个路由应该映射一个组件。 其中"component" 能够是 // 经过 Vue.extend() 建立的组件构造器, // 或者,只是一个组件配置对象。 // 咱们晚点再讨论嵌套路由。 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 建立 router 实例,而后传 `routes` 配置 // 你还能够传别的配置参数, 不过先这么简单着吧。 const router = new VueRouter({ routes // (缩写) 至关于 routes: routes }) // 4. 建立和挂载根实例。 // 记得要经过 router 配置参数注入路由, // 从而让整个应用都有路由功能 const app = new Vue({ router }).$mount('#app') // 如今,应用已经启动了! </script>
提供了跳转或取消导航的能力。分为全局、路由、组件级。
参数或查询的改变并不会触发进入/离开的导航守卫,能够经过观察 $route
对象来应对这些变化,或使用 beforeRouteUpdate
的组件内守卫。github
全局级别是指定义在 router
上,好比 router.beforeEach
。web
beforeEach
全局前置钩子函数。当一个导航触发时,全局前置守卫按照建立顺序调用。守卫是异步解析执行,此时导航在全部守卫 resolve 完以前一直处于 等待中。vue-router
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // to: Route: 即将要进入的目标路由对象 // from: Route: 当前导航正要离开的路由 // next():执行下一个钩子,必须调用,不然会一直等待 // next(false):中断这次跳转 // next(path):跳转到新的地址,通常是权限判断,无权限去登录页 // next(error): (2.4.0+)触发 onError 事件 })
beforeResolve
全局解析钩子函数 ( 2.5.0+)。这和 router.beforeEach
相似,区别是在导航被确认以前,同时在全部组件内守卫和异步路由组件被解析以后,解析守卫就被调用。afterEach
全局后置钩子函数路由级别是指在 routes
定义时设置的。编程
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
组件级别就是指在定义组件时写的了,和 mounted
同级。好比路由改变,可是由于组件共享问题,须要刷新这个时候咱们能够在 beforeRouteUpdate
里面作逻辑,或者 watch
监听 $route
segmentfault
beforeRouteEnter
渲染组件前被调用,没法获取thisbeforeRouteUpdate
(2.2 新增) 在当前路由改变,可是该组件被复用时调用beforeRouteLeave
导航离开该组件的对应路由时调用。能够用来实现禁止用户在还未保存修改时异常离开,提示保存内容。beforeRouteLeave
守卫。beforeEach
守卫。beforeRouteUpdate
守卫 (2.2+)。beforeEnter
。beforeRouteEnter
。beforeResolve
守卫 (2.5+)。afterEach
钩子。beforeRouteEnter
守卫中传给 next
的回调函数,建立好的组件实例会做为回调函数的参数传入。下面的属性介绍,统一都基于下面的配置:
页面URL: https://www.lilnong.top/cors/vueRouter?a=1#b
路由规则:/cors/:key
/cors/vueRouter
this.$route.params.key == 'vueRouter'
this.$route.query.a == '1'
this.$route.hash == '#b'
组件与路由系统解耦,组件开发中咱们通常是定义 props
,可是路由系统倒是 $route
这种冲突破坏了咱们组件,下降了复用性。这个时候咱们在定义 routes
时,给组件设置 props: true
,这样 route.params
将会被设置为组件属性。
props: true
:将 route.params
设置为组件属性props: { aaa: false }
:直接将这个对象,传进去为组件属性props: function
:经过编程的方式生成一个对象,传进去当组件属性路由携带入参(路由元信息 meta),有时候咱们须要给路由设置一些信息,好比是否缓存,能够访问的角色&权限控制。
定义时
const router = new VueRouter({ routes: [ { path: '/config', component: config, meta: {role:['admin']} } ] })
$route.meta.role
。也能够在钩子函数中获取 to.matched.map(record => record.meta.role)
, matched 能够获取到全部被匹配到的路由记录const Foo = () => Promise.resolve({ /* 组件定义对象 */ })
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
,/* webpackChunkName: "group-foo" */
是一个按组分块打包的功能,能够看我的是否使用了。router.addRoutes(routes: Array<RouteConfig>)
watch
监听 $route
来监听改变,也能够经过 beforeRouteUpdate
钩子函数(vueRouter@2.2 版本支持)。*
匹配 404 时,搭配着动态路由使用时,出现没法响应后加的路由问题。这是由于匹配规则是先匹配前面定义的,若是找到就不会继续匹配了(匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。)。因此解决方案就是把404匹配规则也作到动态添加里面。