1. 程式人生 > >vue-router 入門學習

vue-router 入門學習

vue-router

對於單頁面應用,尤其是移動端的網頁應用,使用<a></a>標簽實現頁面切換和跳轉會有300ms的延遲,遇到網速慢就會一直加載。所以在SPA應用中,用視圖切換來模擬頁面的切換


vue-router 是Vue.js官方的路由插件,它和 Vue.js是深度集成的,適用於構建SPA單頁面應用。Vue的單頁面應用是基於路由和組件的,相對於傳統頁面基於 a 鏈接和頁面,路由用於設定訪問路徑,並將路徑和組建映射起來,這樣就可以實現通過路由router來切換組建(視圖)。


vue-router 提供了兩個新組件:<router-link> 和 <router-view>


<router-link> 組件

用於幫助用戶進行視圖導航,默認會被渲染成一個 <a></a>標簽,a 標簽用 href 屬性來制定導航的目標地址,而 router-link 組件則用 to 屬性來指定目標地址


<router-view> 組件負責渲染匹配到的視圖組建,也就是 <router-link>指向的目標地址


先回顧 傳統 a 標簽實現頁面跳轉的寫法:

<div class="router-demo">
    <div class="navbar">
        <a href="https://www.baidu.com/">百度</a>
        <a href="http://www.163.com/">網易</a>
        <a href="http://www.sina.com/">新浪</a>
    </div>
</div>


根據前面的介紹,我們嘗試用 vue-router 來實現頁面跳轉,代碼稍作修改

<div id="app">
    <div class="navbar">
        <!-- 使用 router-link 組件來導航. -->
        <!-- 通過傳入 `to` 屬性指定鏈接. -->
        <!-- <router-link> 默認會被渲染成一個 `<a>` 標簽 -->
        <router-link to="/baidu">百度</router-link>
        <router-link to="/wangyi">網易</router-link>
        <router-link to="/xinlang">新浪</router-link>
    </div>
    <div class="content">
        <!-- 路由出口 -->
        <!-- 路由匹配到的組件將渲染在這裏 -->
        <router-view></router-view>
    </div>
</div>


接下來編寫js部分


1、定義組件

在 components 目錄下分別新建三個組件

技術分享


2、定義路由

技術分享


運行 npm run dev 查看頁面效果

技術分享

三個 <router-link> 組件被渲染成了 <a> 標簽,而 to 屬性也變成了<a> 標簽的 href 屬性,再看看 <router-view> 也被渲染成對應的視圖組件

技術分享


https://router.vuejs.org/zh-cn/

根據官網的講解,可以一步一步的實現上面這個簡單的小demo,接下來,繼續學習


router.js 的配置


mode:

默認為 hash,使用 hash 模式時,頁面的路由地址會加一個 #,如上例所示: http://localhost:8080/#/wangyi


可以采用 history 模式來取消這個 #

技術分享

技術分享


base:

應用的基路徑,例如,如果整個單頁應用服務在 /app/ 下,base 就應該設為 “/app/”,一般寫成 __dirname,在webpack 中有配置

技術分享


routes:

包含了所有的頁面配置,其中:

path: 就是訪問的頁面路徑

name: 必須唯一,給頁面路徑定義的名字,頁面跳轉時,也可以用名字來跳

component: 組件,通過 import 導入。還有另一種寫法 ---> 懶加載


懶加載的方式不需要用 import 引入組件,好處是當你訪問該頁面時才加載相關資源,這樣的話就能提高頁面的訪問速度

component: resolve => require([‘../components/Baidu.vue‘], resolve)

技術分享


編程式導航


除了 <router-link> 創建 a 標簽來定義導航鏈接,我們還可以借助 router 的實例方法,通過編寫代碼來實現


router.push( location )


想要導航到不同的 url,則使用 router.push 方法,這個方法會向 history 棧添加一個新的記錄。所以,當用戶點擊瀏覽器回退按鈕時,則回到之前的 url

聲明式編程式
<router-link :to="...">
router.push( ... )


該方法的參數可以是一個字符串路徑,也可以是一個描述地址的對象,例如:

// 字符串
router.push (‘home‘)

// 對象
router.push ({path: ‘home‘})

// 命名的路由
router.push ({name: ‘user‘, params: { userId: 123 }})

// 帶查詢參數,變成 /regsiter ? plan = private
router.push ({path: ‘register‘, query: { plan: ‘private‘}})


router.replace ( location )


跟 router.push 很像,唯一不同的是,它不會像 history 添加新的記錄,而是跟它的方法名一樣 --- 替換掉當前的 history 記錄

聲明式編程式
<router-link :to = " ... " replace>router.replace ( ... )


router.go ( n )


這個方法的參數是一個整數,意思是在history 記錄中向前或者後退多少步,類似 window.history.go( n )

// 在瀏覽器中前進一步,等同於 history.forward( )
router.go ( 1 )

// 後退一步記錄,等同於 history.back( )
router.go ( -1 )

// 前進 3步記錄
router.go ( 3 )

//


導航鉤子


正如其名,vue-router 提供的導航鉤子用來 攔截導航,讓它完成跳轉或取消。比如做登錄的攔截,而鉤子函數根據其生效的範圍可以分為:全局鉤子函數路由獨享鉤子函數組件內鉤子函數


全局鉤子函數

可以直接在路由配置文件 router.js 裏編寫代碼邏輯,可以做一些全局性的路由攔截,例如:用 router.beforeEach 註冊一個全局的 before 鉤子:

router.beforeEach ( (to, from, next) => {
    //do something
    next()
})

router.afterEach ( (to, from, next) => {
    console.log( to.path )
})


當一個導航觸發時,全局的 before 鉤子按照創建順序調用,鉤子是異步解析執行,此時導航在所有鉤子 resolve 之前一直處於 等待中


每個鉤子方法接收 三個參數:

to: Route: 即將要進入的目標,路由對象

from: Route: 當前導航正要離開的路由

next: Function:一定要調用該方法來 resolve 這個鉤子,執行結果依賴 next( ) 方法的調用參數


> next(): 進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。


> next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了(可能是用戶手動或者瀏覽器後退按鈕),那麽 URL 地址會重置到 from 路由對應的地址。


> next(‘/‘) 或者 next({ path: ‘/‘ }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。


確保要調用 next 方法,否則鉤子就不會被 resolved。


同樣可以註冊一個全局的 after 鉤子,不過它不像 before 鉤子那樣,after 鉤子沒有 next 方法,不能改變導航:

router.afterEach(
    route => {  // ...}
)


路由獨享鉤子函數


可以做一些單個路由的跳轉攔截,在配置文件編寫代碼即可

const router = new Router({
    routes: [
        {
            path: ‘/foo‘,
            component: Foo,
            beforeEnter: (to, from, next) => {
                // ...
            }
        }
    ]
})


組件內鉤子函數


更細粒度的路由攔截,只針對一個進入某一個組件的攔截,可以在路由組件內直接定義以下路由導航鉤子

beforeRouteEnter

beforeRouteUpdate (2.2 新增)

beforeRouteLeave

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`
  }
}


beforeRouteEnter 鉤子 不能 訪問 this,因為鉤子在導航確認前被調用,因此即將登場的新組件還沒被創建。


不過,你可以通過傳一個回調給 next來訪問組件實例。在導航被確認的時候執行回調,並且把組件實例作為回調方法的參數。

beforeRouteEnter (to, from, next) {
  next(vm => {    // 通過 `vm` 訪問組件實例
  })
}


你可以 在 beforeRouteLeave 中直接訪問 this。這個 leave 鉤子通常用來禁止用戶在還未保存修改前突然離開。可以通過 next(false) 來取消導航。


鉤子函數使用場景


其實路由鉤子函數在項目開發中用的並不是非常多,一般用於登錄態的校驗,沒有登錄跳轉到登錄頁;權限的校驗等等。當然隨著項目的開發進展,也會有更多的功能可能用鉤子函數實現會更好,我們知道有鉤子函數這個好東西就行了,下次遇到問題腦海就能浮現,這個功能用鉤子實現會比較棒


滾動行為


在利用vue-router去做跳轉的時候,到了新頁面如果對頁面的滾動條位置有要求的話,可以利用下面這個方法

const router = new VueRouter({  routes: [...],
  scrollBehavior (to, from, savedPosition) {    
    // return 期望滾動到哪個的位置
  }
})


scrollBehavior 方法接收 to 和 from 路由對象。

第三個參數 savedPosition 當且僅當 popstate 導航 (mode為 history 通過瀏覽器的 前進/後退 按鈕觸發) 時才可用。

//所有路由新頁面滾動到頂部:
scrollBehavior (to, from, savedPosition) {  
    return { x: 0, y: 0 }
}
//如果有錨點
scrollBehavior (to, from, savedPosition) {  
    if (to.hash) {    
        return {      
            selector: to.hash
        }
    }
}

























vue-router 入門學習