路由組件傳參html
經過props解耦vue
const User = { props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: true }, // 對於包含命名視圖的路由,你必須分別爲每一個命名視圖添加 `props` 選項: { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ] })
布爾模式vue-router
若是props被設置爲true,route.params參數將被設置爲組件屬性app
對象模式ide
const router = new VueRouter({ routes: [ { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } } ] })
函數模式函數
/search?q=vue 會將{query:vue}傳遞給組件SearchUserpost
const router = new VueRouter({ routes: [ { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) } ] })
History模式fetch
vue-router默認使用hash模式ui
const router = new VueRouter({ mode: 'history', routes: [...] })
若是使用history模式,URL就像正常url,http://mysite.com/user/idthis
這種模式須要後臺配置
警告:全部路徑都會返回index.html,所以須要配置一個404頁面
const router = new VueRouter({ mode: 'history', routes: [ { path: '*', component: NotFoundComponent } ] })
導航守衛
全局前置守衛
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
三個參數
to:即將進入的Route
from:當前導航離開的Route
next:
next()進行管道中的下一個鉤子
next(false)中斷當前導航
next('/')或next({path:'/'}) 中斷當前導航,跳轉到下一個導航
一個登錄案例,根據用戶是否登陸判斷路由跳轉
router.beforeEach((to, from, next) => { // 若是不是登陸頁 if (to.name !== 'login') { if (HAS_LOGIN) next() else next({ name: 'login' }) } else { if (HAS_LOGIN) next({ name: 'home' }) else next() } })
全局後置鉤子
router.afterEach((to, from) => { // ... })
一個頁面加載的案例。loading設置
路由獨享守衛
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
組件內的守衛
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 由於當守衛執行前,組件實例還沒被建立 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` } }
完整的導航流出
https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#組件內的守衛
路由元信息
定義路由能夠配置meta字段
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, // a meta field meta: { requiresAuth: true } } ] } ] })
咱們在全局導航守衛中調用
case
router.beforeEach((to, from, next) => { console.log(to) })
fullPath: "/foo/bar" hash: "" matched: (2) [{…}, {…}] meta: {requireAuth: true} name: "bar" params: {} path: "/foo/bar" query: {} __proto__: Object
咱們能從to中得到meta中數據
router.beforeEach((to, from, next) => { const requireAuth = to.meta.requireAuth if (requireAuth) { if (HAS_LOGIN) next() else next({ 'name': 'login' }) } else { next() } })
過渡效果
<transition> <router-view></router-view> </transition>
單個路由過渡
const Foo = { template: ` <transition name="slide"> <div class="foo">...</div> </transition> ` } const Bar = { template: ` <transition name="fade"> <div class="bar">...</div> </transition> ` }
數據獲取
導航完成後獲取數據
$router.params.id得到文章數據
<template> <div class="post"> <div class="loading" v-if="loading"> Loading... </div> <div v-if="error" class="error"> {{ error }} </div> <div v-if="post" class="content"> <h2>{{ post.title }}</h2> <p>{{ post.body }}</p> </div> </div> </template>
export default { data () { return { loading: false, post: null, error: null } }, created () { // 組件建立完後獲取數據, // 此時 data 已經被 observed 了 this.fetchData() }, watch: { // 若是路由有變化,會再次執行該方法 '$route': 'fetchData' }, methods: { fetchData () { this.error = this.post = null this.loading = true // replace getPost with your data fetching util / API wrapper getPost(this.$route.params.id, (err, post) => { this.loading = false if (err) { this.error = err.toString() } else { this.post = post } }) } } }
在導航完成前得到數據beforeRouterEnter
export default { data () { return { post: null, error: null } }, beforeRouteEnter (to, from, next) { getPost(to.params.id, (err, post) => { next(vm => vm.setData(err, post)) }) }, // 路由改變前,組件就已經渲染完了 // 邏輯稍稍不一樣 beforeRouteUpdate (to, from, next) { this.post = null getPost(to.params.id, (err, post) => { this.setData(err, post) next() }) }, methods: { setData (err, post) { if (err) { this.error = err.toString() } else { this.post = post } } } }
滾動行爲
const router = new VueRouter({ routes: [...], scrollBehavior (to, from, savedPosition) { // return 指望滾動到哪一個的位置 } })
當切換到新的路由時候,想要頁面滾動到頂部,或者原先的位置
scrollBehavior (to, from, savedPosition) { return { x: 0, y: 0 } }
路由懶加載
const Foo = () => import('./Foo.vue')
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ] })