前端最基礎的就是 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匹配規則也作到動態添加里面。