vue router的理解

此文章用來系統講解vue-router路由

vue生命週期

1. 安裝

只介紹npm安裝
npm install vue-router --save 項目所需依賴
在main.js或者app.vue中導入
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
現在你就可以開始使用vue-router了

2.結構

先來簡單的瞭解一下使用的結構,方便後面學習
<router-link to="/foo">Go to Foo</router-link> 相當於a標籤
<router-view></router-view> 這時用來渲染匹配到的路由組件的
下面就是具體的路由設置了
const app = new Vue({
    router: new VueRouter({
        routes: [
            {path: '/foo',component: Foo} //匹配到路由'/foo'後渲染組件Foo
        ]
    })
}).$mount("#app")

3.動態路由匹配

說簡單點,就是不同的路由值,訪問同一個組件
例如:
    const router = new VueRouter({
        routes: [
            { path: '/user/:id', component: User }
        ]
    })
    在 '/user/' 後面跟個 :id 表示這時可選的,就是說不管id是啥,都可以訪問User組件
    並且這個id存放在this.$route.params中,並且可以有多個這樣的可選值
注意點: 在不同的路由值之間切換訪問相同的組件,是不會重複渲染的,但是可以通過watch來做出響應
    const User = {
        watch: {
            '$route' (to,from) {
                // 對路由變化做出響應
            }
        }
    }
    // 有沒有覺得這個寫法挺怪的,管他呢,能用就行O(∩_∩)O哈哈~

4.嵌套路由

嵌套路由很簡單,就是匹配到某個路由值,渲染到一個組件,這個組件內部還有router-view,這時可以傳遞第二段路由值,加以匹配,如果不傳遞,可以設置一個空的二段路由值
例子如下:
    const router = new VueRouter({
        routes: [{
            path: '/user/:id',component: User
        }]
    })
    /user/demo 這個路由值,可以匹配到User組件,如果User組件是如下的
    const User = {
        template: `
            <router-view></router-view>
        `
    }
    那麼需要對路由配置做如下修改
    const router = new Router({
        routes: [
            {path: '/user/:id',component: User,
             children: [
                 {path: '',component: UserHome},
                 {path: 'profile',component: UserProfile}
             ]
            }
        ]
    })

5.編程式導航

簡而言之,就是,使用js來實現router-link的功能
使用 router.push ,此方法和router-link一模一樣,回產生瀏覽記錄,有如下幾種形式,和router-link是等價的
    router.push('home')
    router.push({path: 'home'}) // 和上面等價
    router.push({name: 'user',params: {userId: 123}}) // 這個是命名路由,後面講
    router.push({path: 'register',query: {plan: 'private'}}) // '/register?plan=private'
使用router.replace(location)
    和router.push相似,只不過這裏不會產生瀏覽記錄,沒卵用
使用router.go(n) 基本用不到,沒卵用

6.命名路由

命名路由是用來給懶人用的,給router-link傳遞to屬性,使用path很長,很難寫,所以,起個名字,方便寫
當某個路由配置是
const router = new VueRouter({
    routes: [
        {
            path: '/user/:userId',
            name: 'user',
            component: User
        }
    ]
})
正常人是這樣訪問的 <router-link :to="/user/123"></router-link>
懶人是這樣訪問的 <router-link :to="{name: 'user',params: {userId: 123}}"></router-link>
咦。。。,好像還要多輸入幾個字符,不對,這是裝逼用的

7.命名視圖

這個玩意兒就是當匹配到一個路由值,同時渲染多個組件,很簡單,看下面demo
<router-view></router-view> //這個沒有起名的默認就是 default
<router-view name="a"></router-view>
<router-view name="b"></router-view>
const router = new VueRouter({
    routes: [
        {
            path: '/',
            components: {
                default: Foo,
                a: Bar,
                b: Baz
            }
        }
    ]
})
// 這樣同時就渲染出 Foo,Bar,Baz 三個組件了

8.重定向和別名

這兩個概念也是很簡單的
重定向就是當訪問一個路由值,定向到另外一個路由值,此即以假亂真,簡單demo如下
const router = new VueRouter({
    routes: [
        {path: '/a',redirect: '/b'}
    ]
})
別名就是起個其它的名字,其實方法的還是這個路由
const router = new VueRouter({
    routes: [
        {path: '/a',component: A,alias: '/b'}
    ]
})

9.HTML5 History模式

這部分內容也是裝逼專用,就是把url中的/#去掉,變好看一點,需要把其他不符合要求的路由值定位到主頁上來,要不然就直接404,官網說這個功能要後臺來實現,不過我覺得,可以直接用路由鉤子實現,詳見後述

10.導航鉤子

這個功能很強大,可以在進行導航的過程的各個時間點做處理,很吊的
有全局的,單個路由的,組件的
1.先來看個全局的鉤子,註冊一個全局的before鉤子
const router = new VueRouter({...});
router.beforeEach((to,from,next) => {
    // 可以註冊多個before,多個before之間是異步的,但是導航必須等到這些鉤子執行完成,纔開始
    // to 目標路由對象
    // from 當前路由對象
    // next 有如下幾種用法
    // next() 執行下一個鉤子函數,沒有鉤子,則to到目標路由
    // next(false) 不to了,直接留在from這個路由
    // next('/') 不管這個to了,另找了一個to
    // next方法必須調用,不調用就是死循環,小心你電腦內存爆了
    // 記得剛開始學這個,我差點把電腦砸了
})
註冊一個after鉤子,這個作用不大,畢竟路由都跳轉了,唯一的作用就是來看看而已
router.afterEach(route => {
    // ...
})
2.單個路由的
直接上demo了吧,簡單
const router = new VueRouter({
    routes: [{
        path: '/foo',
        component: Foo,
        beforeEnter: (to,from,next) => {
            //...
        }
    }]
})
3.組件內的
這個也簡單,不過比上面兩個稍有點區別,上demo吧
const Foo = {
    template: '...',
    beforeRouteEnter (to,from,next) {
        // 這裏不能直接訪問當前實例this,因爲實例還沒有渲染,不過可以通過next來訪問
        next(vm => {
            // ...
        })
    },
    beforeRouteUpdate (to,from,next) {
        // 多個路由值訪問同一個組件,來回切換,組件不會刷新,那麼上面的這個鉤子就沒有了,此時這個鉤子登場
    },
    beforeRouteLeave (to,from,next) {
        // 顧名思義,不介紹了
    }
}

11.路由元信息

這玩意兒就是一個flag,用於遍歷的時候找到特殊的路由,用處很小,這裏不介紹了,感興趣自己查去

12.過渡動效

就是在切換路由的時候展示動畫,如果你懂vue的transition,這部分內容你根本就不用看,直接上手
<transition>
    <router-view></router-view>
</transition>

13.數據獲取

在切換到其他路由,其他路由獲取數據有兩種方式,渲染完成之後獲取數據,渲染之前獲取數據
1.渲染完成之後獲取數據
正常人都是這麼幹的,就是在組件的created鉤子中寫api獲取數據,不做介紹了
2.渲染之前獲取數據
這個還是很經典的,很有實際價值
在接下來要切換的組件中的beforeRouteEnter中獲取數據,數據獲取完成之後再渲染,再添加一個渲染動畫,感覺棒棒噠
在next(vm => {
    // 將獲取的數據放到實例上,上面介紹過了
})
上面這個也可以通過監聽$route來實現,不過有點稍微延遲,不推薦使用
watch: {
    $route(){
        ...
    }
}

14.滾動行爲

這個還是有點用的,切換到一個新的路由組件時,控制頁面的位置
藉助scrollBehavior方法,這個方法要寫在router實例中
const router = new VueRouter({
    routes: [...],
    scrollBehavior (to,from,savedPosition) {
        savedPosition是點擊瀏覽器的前進後退按鈕才管用,下面列舉了幾種使用demo
        return {x: 0,y: 0}; 簡單的回到最頂部
        return savedPosition; 返回原先的位置
        if (to.hash) {
            return {selector: to.hash} 錨點定位
        }
    }
})

15.懶加載

將組件拆分,實現按需加載,有如下幾種方式,以後添加組件的話都這樣用
1.把路由對應的組件拆分成異步組件
const Foo = resolve => {
    require.ensure(['./Foo.vue'], () => {
        resolve(require('./Foo.vue'))
    })
}
2.AMD
const Foo = resolve => require(['./Foo.vue'], resolve)
3.將多個組件打包到一個模塊中
const Foo = r => require.ensure([], () => r(require('./Foo.vue')), 'group-foo')
const Bar = r => require.ensure([], () => r(require('./Bar.vue')), 'group-foo')
const Baz = r => require.ensure([], () => r(require('./Baz.vue')), 'group-foo')

忘記轉的哪位大神的了~~~ 轉自:未知

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章