Vue學習筆記(十) Vue Router

一、簡介

Vue Router 是 Vue.js 的官方路由管理器,在官方文檔中描述的功能包括:html

  • 嵌套的路由/視圖表
  • 模塊化的、基於組件的路由配置
  • 路由參數、查詢、通配符
  • 基於 Vue.js 過渡系統的視圖過渡效果
  • 細粒度的導航控制
  • 帶有自動激活的 CSS class 的連接
  • HTML5 history 模式或 hash 模式,在 IE9 中自動降級
  • 自定義的滾動條行爲

這裏,仍是先附上官方文檔的連接:https://router.vuejs.org/zh/vue

二、安裝

(1)經過 CDN 引用java

<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

(2)經過 NPM 安裝與使用vue-router

  • 安裝
> npm install vue-router
  • 使用

在項目中須要經過 Vue.use() 明確安裝路由功能shell

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

三、入門

下面,咱們用一個簡單的例子來體會一下 Vue Router 的基本使用方法npm

首先建立一個命名爲 index.html 的文件,而後在文件中輸入以下代碼(具體請看代碼註釋):編程

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <h1>Hello</h1>
        <p>
            <!-- 默認渲染成 <a> 標籤,經過 to 屬性指定路徑 -->
            <router-link to="/home">Home</router-link> | 
            <router-link to="/about">About</router-link>
        </p>
        <!-- 路由匹配到的組件渲染到這裏 -->
        <router-view></router-view>
    </div>

    <script>
        // 一、定義組件
        const Home = {
            template: `
                <div>
                    <h3>Home Page Here</h3>
                    <p>This is home page</p>
                </div>
            `
        }
        const About = {
            template: `
                <div>
                    <h3>About Page Here</h3>
                    <p>This is about page</p>
                </div>
            `
        }

        // 二、定義路由
        const routes = [
            {
                path: '/home', // 匹配的路徑
                component: Home // 顯示的組件
            },
            {
                path: '/about',
                component: About
            }
        ]

        // 三、建立 router 實例,傳入 routes 配置
        const router = new VueRouter({
            routes // 縮寫,至關於 routes : routes
        })

        // 四、建立並掛載根實例
        const app = new Vue({
            router // 注入路由
        }).$mount('#app')
    </script>
</body>

</html>

當咱們打開頁面時,URL 爲 index.html#/app

若是咱們點擊 Home,URL 跳轉爲 index.html#/home(此時,匹配路由 /home,顯示組件 Home)模塊化

若是點擊 About,URL 跳轉爲 index.html#/about(此時,匹配路由 /about,顯示組件 About)

四、動態路由

下面考慮這樣一個需求,咱們要爲路由 /user/Alice/user/Bob 指定使用同一個組件 User

再泛化一點來講就是爲每個不一樣的用戶(路由爲 /user/xxx)都指定使用同一個組件

這時候,動態路由就能夠派上用場啦

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <h1>Hello</h1>
        <router-view></router-view>
    </div>

    <script>
        const User = {
            // 在模板中咱們能夠用 $route 對象中的 params 屬性得到 URL 參數
            template: '<p>The user name is {{ $route.params.name }}</p>'
        }

        const routes = [
            {
                path: '/user/:name', // 以冒號開頭表示參數,能夠同時使用多個參數
                component: User
            }
        ]

        const router = new VueRouter({
            routes
        })

        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>

這時候,咱們手動輸入 URL index.html#/user/Alice,頁面會顯示 The user name is Alice

若是再輸入 index.html#/user/Bob,頁面顯示會變成 The user name is Bob

可是須要注意,從 /user/Alice 導航到 /user/Bob,原來的組件將會被複用,而不是從新建立

這意味着什麼?這意味着組件的生命週期鉤子不會再被調用

若是但願路由參數變化時組件可以做出響應,有兩個辦法:

  1. 使用 watch 屬性監測 $route 對象
const User = {
    template: `
        <div>
            <p>The user name is {{ $route.params.name }}</p>
        </div>
    `,
    watch: {
        '$route': function (to, from) {
            console.log('changed')
        }
    }
}
  1. 使用 beforeRouteUpdate 導航護衛
const User = {
    template: `
        <div>
            <p>The user name is {{ $route.params.name }}</p>
        </div>
    `,
    beforeRouteUpdate (to, from, next) {
        console.log('changed')
    }
}

五、命名路由

在上面的例子中,咱們使用 path 標識一個路由,事實上,咱們還可使用 name 爲路由設置名稱

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <h1>Hello</h1>
        <!-- 在連接到一個命名路由時,須要給 <router-link> 元素的 to 屬性動態綁定一個對象 -->
        <router-link :to="{ name: 'user', params: { name: 'Alice'} }">To Alice User Page</router-link>
    </div>

    <script>
        const User = {
            template: '<p>The user name is {{ $route.params.name }}</p>'
        }

        const routes = [
            {
                name: 'user', // 爲路由設置名稱
                path: '/user/:name',
                component: User
            }
        ]

        const router = new VueRouter({
            routes
        })

        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>

六、命名視圖

與上面相似,咱們可使用 name<router-view> 設置名稱,這容許咱們在一個路由中使用多個同級的視圖

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <h1>Hello</h1>
        <router-link to="/home">To Home Page</router-link>
        <router-view name="header"></router-view> <!-- 爲視圖設置名稱 -->
        <router-view></router-view> <!-- 沒有命名,默認爲 default -->
        <router-view name="footer"></router-view>
    </div>

    <script>
        const Header = { template: '<h3>This is header</h3>' }
        const Container = { template: '<span>This is container</span>' }
        const Footer = { template: '<p>This is footer</p>' }

        const routes = [
            {
                path: '/home',
                // 使用 components 選項,不是 component
                components: { // 對象,鍵爲視圖名稱,值爲組件名稱
                    default: Container,
                    header: Header,
                    footer: Footer
                }
            }
        ]

        const router = new VueRouter({
            routes
        })

        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>

七、嵌套路由

在實際應用中,除了會有使用多個同級視圖的狀況,還有使用嵌套視圖的狀況,這時候咱們有嵌套路由與之匹配

<!DOCTYPE html>
<html>

<head>
    <title>Demo</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>

<body>
    <div id="app">
        <h1>Hello</h1>
        <router-link to="/home">To Home Page</router-link>
        <router-link to="/home/intro">To Intro Page</router-link>
        <router-link to="/home/info">To Info Page</router-link>
        <router-view></router-view>
    </div>

    <script>
        const Home = {
            // 在組件中也能夠包含 <router-view>
            template: `
                <div>
                    <p>This is home page</p>
                    <router-view></router-view>
                </div>
            `
        }
        const Info = { template: '<p>This is info page</p>' }
        const Intro = { template: '<p>This is intro page</p>' }

        const routes = [
            {
                path: '/home',
                component: Home,
                // 使用 children 選項,至關於在子組件中配置 routes
                children: [
                    {
                        path: 'intro', // 至關於 /home/intro
                        component: Intro // 渲染在 Home 的 <router-view> 中
                    },
                    {
                        path: 'info', // 至關於 /home/info
                        component: Info // 渲染在 Home 的 <router-view> 中
                    }
                ]
            }
        ]

        const router = new VueRouter({
            routes
        })

        const app = new Vue({
            router
        }).$mount('#app')
    </script>
</body>

</html>

八、組件傳參

還記得在動態路由那一小節的例子嗎?咱們使用 $route.params 獲取 URL 參數

const User = {
    template: '<p>The user name is {{ $route.params.name }}</p>'
}

const routes = [
    {
        path: '/user/:name',
        component: User
    }
]

這樣的寫法,使得組件與對應的路由高度耦合,因此咱們可使用 props 進行解耦

const User = {
    props: ['name'], // 使用 props 屬性
    template: '<p>The user name is {{ name }}</p>'
}

const routes = [
    {
        path: '/user/:name',
        component: User,
        props: true // 使用 props 屬性,除了使用布爾值,還可使用對象和函數
    }
]

九、編程式導航

在上面的例子中咱們屢次使用 <router-link> 進行導航,實際上咱們還可使用 router.push()

該方法有三個參數,分別是 location、onComplete 和 onAbort,它們的含義以下:

  • location:指定目標 URL,能夠是字符串或對象
  • onComplete:導航成功後的回調函數
  • onAbort:導航終止後的回調函數

router.replace()router.push() 十分相似

不一樣之處在於 push 會向 history 棧中添加新的記錄,而 replace() 將會直接替換當前的 history 記錄

【 閱讀更多 Vue 系列文章,請看 Vue學習筆記

相關文章
相關標籤/搜索