Vue.js 2.x筆記:路由Vue Router(6)

libingql發表於2018-06-13

1. Vue Router簡介與安裝

1.1 Vue Router簡介

  Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度整合,構建單頁面應用。

  Vue Router支援3種路由模式:

    ◊ hash:使用URL hash值作為路由

    ◊ history:依賴HTML5 History API和伺服器配置

    ◊ abstract:支援所有JavaScript執行環境,如node伺服器端。如果發現沒有瀏覽器的API,路由就會強制進入該模式。

  vue-router提供兩個指令標籤元件來處理這個導航與自動渲染邏輯:

    ◊ <router-view>:渲染路徑匹配到的元件檢視

    ◊ <router-link>:支援使用者在具有路由功能的應用中導航

1.2 Vue Router安裝

  Vue Router官方網址:https://github.com/vuejs/vue-router

  Vue Router文件教程:https://router.vuejs.org/zh/

  npm安裝VueRouter:

npm install vue-router

2. 起步示例

2.1 單個html頁面中使用

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>libing.vue</title>
    <script src="node_modules/vue/dist/vue.min.js"></script>
    <script src="node_modules/vue-router/dist/vue-router.min.js"></script>
</head>

<body>
    <div id="app">
        <ul>
            <li>
                <router-link to="/home">Home</router-link>
            </li>
            <li>
                <router-link to="/about">About</router-link>
            </li>
        </ul>
        <router-view></router-view>
    </div>

    <template id="home">
        <div>Home</div>
    </template>
    <template id="about">
        <div>About</div>
    </template>

    <script>
        var home = Vue.extend({
            template: "#home"
        });
        var about = Vue.extend({
            template: "#about"
        });

        const routes = [{
                path: '/home',
                component: home
            },{
                path: '/about',
                component: about
            }
        ];

        const router = new VueRouter({
            routes: routes
        });

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

</html>

2.2 vue-cli中模組化使用

  (1)建立基於vue-cli專案

$ vue init webpack libing.vue

  專案結構:

  (2)/src/views中新建Home.vue及About.vue

<template>
    <div>{{ title }}</div>
</template>

<script>
export default {
    data: function() {
        return {
            title: "主頁"
        };
    }
};
</script>
Home.vue
<template>
    <div>{{ title }}</div>
</template>

<script>
export default {
    data: function() {
        return {
            title: "關於"
        };
    }
};
</script>
About.vue

  (3)/src/route/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import About from '@/views/About'

Vue.use(Router)

export default new Router({
    routes: [{
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/home',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: About
        }
    ]
})

  (4)/src/App.vue

<template>
    <div id="app">
        <ul>
            <li>
                <router-link to="/home">Home</router-link>
            </li>
            <li>
                <router-link to="/about">About</router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "App"
};
</script>

  其餘未做改動部分:

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
/src/main.js
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>libing.vue</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
index.html

  在router-link通過名稱引用路由:向to屬性傳入一個物件顯式的宣告路由的名稱。

<router-link :to="{ name: 'home' }">Home</router-link>

注:在/src/route/index.js中配置路由路徑時,建立Router 物件new Router({}),如果不配置 mode,就會使用預設的 hash 模式,該模式下會將路徑格式化為 #! 開頭。
      設定 mode: "history" 將使用 HTML5 history 模式,該模式下沒有 # 字首,而且可以使用 pushState 和 replaceState 來管理記錄。

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import About from '@/views/About'

Vue.use(Router)

export default new Router({
    mode: 'history',
    routes: [{
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/home',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: About
        }
    ]
})

3. 動態路由匹配

  在 vue-router 的路由路徑中使用“動態路徑引數”(dynamic segment) ,動態部分 以 : 開頭。

  /src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import About from '@/views/About'
import User from '@/views/User'

Vue.use(Router)

export default new Router({
    mode: 'history',
    routes: [{
            path: '/',
            component: Home
        },
        {
            path: '/home',
            component: Home
        },
        {
            path: '/about',
            component: About
        },
        {
            // 動態路徑引數 以冒號開頭
            path: '/user/:id',
            component: User
        }
    ]
})

  User.vue:

<template>
    <div>User ID:{{ $route.params.id }}</div>
</template>

<script>
export default {
    
}
</script>

  App.vue:

<template>
    <div id="app">
        <ul>
            <li>
                <router-link to="/home">Home</router-link>
            </li>
            <li>
                <router-link to="/about">About</router-link>
            </li>
            <li>
                <router-link to="/user/1">User ID:1</router-link>
            </li>
            <li>
                <router-link to="/user/2">User ID:2</router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "App"
};
</script>

  在User.vue中直接通過 {{ $route.params.id }} 獲取路由中路徑引數值。

  當整個vue-router 注入到根例項後,在元件的內部,可以通過this.$route 來獲取到 router 例項。

  $route中params 屬性來獲得動態部分,params 屬性是一個物件。

  屬性名是路徑中定義的動態部分 id, 屬性值是router-link中to 屬性中的動態部分。

 

  在<router-link>中加入一個params的屬性來指定具體的引數值。

<router-link :to="{ name: 'user', params:{ id: 1 }}">UserID:1</router-link>

4. 巢狀路由

  實際應用介面,通常由多層巢狀的元件組合而成。

  vue-router配置巢狀路示例:

  App.vue

<template>
    <div id="app">
        <ul>
            <li>
                <router-link to="/home">Home</router-link>
            </li>
            <li>
                <router-link :to="{ name: 'about' }">About</router-link>
            </li>
            <li>
                <router-link :to="{ name: 'user', params:{ id: 1 }}">UserID:1</router-link>
            </li>
            <li>
                <router-link to="/user/2">UserID:2</router-link>
            </li>
        </ul>
        <router-view/>
    </div>
</template>

<script>
export default {
    name: "App"
};
</script>

  這裡的<router-view>是最頂層的出口,渲染最高階路由匹配到的元件。

  一個被渲染元件同樣可以包含自己的巢狀 <router-view>。

  User.vue

<template>
    <div>
        <h2>User ID:{{ $route.params.id }}</h2>
        <router-view></router-view>
    </div>
</template>

<script>
export default {};
</script>

  要在巢狀的出口中渲染元件,需要在 VueRouter 的引數中使用 children 配置:

  index.js

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import About from '@/views/About'
import User from '@/views/User'
import UserProfile from '@/views/UserProfile'

Vue.use(Router)

export default new Router({
    mode: 'history',
    routes: [{
            path: '/',
            name: 'home',
            component: Home
        },
        {
            path: '/home',
            name: 'home',
            component: Home
        },
        {
            path: '/about',
            name: 'about',
            component: About
        },
        {
            // 動態路徑引數 以冒號開頭
            path: '/user/:id',
            name: 'user',
            component: User,
            children: [{
                // 當 /user/:id/profile 匹配成功,
                // UserProfile 會被渲染在 User 的 <router-view> 中
                path: 'profile',
                name: 'profile',
                component: UserProfile
            }]
        }
    ]
})

  UserProfile.vue

<template>
    <div>User Profile</div>
</template>

<script>
export default {};
</script>

  訪問巢狀路由方式:http://localhost:8080/user/1/profile

  在巢狀路由中訪問父級路由引數:

<template>
    <div>User Profile:{{ $route.params.id }}</div>
</template>

<script>
export default {};
</script>

  當訪問 /user/1 時,提供一個 空的子路由。

{
    // 動態路徑引數 以冒號開頭
    path: '/user/:id',
    name: 'user',
    component: User,
    children: [{
        // 當 /user/:id 匹配成功,
        // UserProfile 會被渲染在 User 的 <router-view> 中
        path: '',
        component: UserProfile
    }, {
        // 當 /user/:id/profile 匹配成功,
        // UserProfile 會被渲染在 User 的 <router-view> 中
        path: 'profile',
        name: 'profile',
        component: UserProfile
    }]
}

5. 命名檢視

  若要同級展示多個檢視(非巢狀),使用命名檢視。

  如果router-view沒有設定名字,則預設為 default。

<router-view name="main"></router-view>

  一個檢視使用一個元件渲染,因此對於同個路由,多個檢視就需要多個元件。使用 components 配置。

<router-view name="header"></router-view>
<router-view name="slidebar"></router-view>
<router-view name="main"></router-view>
<router-view name="footer"></router-view>

  Route配置:

export default new Router({
    routes: [{
            path: '/',
            name: 'home',
            components: {
                default: Home,
                header: Header,
                slidebar: SlideBar,
                footer: Footer
            }
        }
    ]
})

  命名巢狀檢視:

<template>
    <div>
        <h2>User ID:{{ $route.params.id }}</h2>
        <router-view></router-view>
        <router-view name="defined"></router-view>
    </div>
</template>

<script>
export default {};
</script>
export default new Router({
    routes: [{
            // 動態路徑引數 以冒號開頭
            path: '/user/:id',
            name: 'user',
            component: User,
            children: [{
                // 當 /user/:id 匹配成功,
                // UserProfile 會被渲染在 User 的 <router-view> 中
                path: '',
                component: UserProfile
            }, {
                // 當 /user/:id/profile 匹配成功,
                // UserProfile 會被渲染在 User 的 <router-view> 中
                path: 'profile',
                name: 'profile',
                components: {
                    default: UserProfile,
                    defined: UserDefinedProfile
                }
            }]
        }
    ]
})

 

相關文章