第十四節:VueRouter4.x簡介、基本用法、路由懶加載(打包分析)、動態路由、路由嵌套、相關Api


一. 簡介和基本用法

1. 簡介

 (官網地址:https://next.router.vuejs.org/zh/introduction.html)

 Vue Router 是 Vue.js 的官方路由。它與 Vue.js 核心深度集成,讓用 Vue.js 構建單頁應用變得輕而易舉。功能包括:

  • 嵌套路由映射
  • 動態路由選擇
  • 模塊化、基於組件的路由配置
  • 路由參數、查詢、通配符
  • 展示由 Vue.js 的過渡系統提供的過渡效果
  • 細致的導航控制
  • 自動激活 CSS 類的鏈接
  • HTML5 history 模式或 hash 模式
  • 可定制的滾動行為
  • URL 的正確編碼

PS:本章節使用的VueRouter版本為4.0.12

2. 基本用法

(1). 通過VueCli創建項目,並且選擇包含VueRouter,會自動導入並生成VueRouter的相關配置文件

 A. 核心配置文件:src/router/index.js  (默認生成的文件如下,后面自己改造)

import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router
View Code

 B. main.js中需要以類似插件的形式導入vuerouter

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

(2). 在Views文件夾里創建兩個組件頁面 Home.vue 和 About.vue ,代碼如下

Home.vue

<template>
    <div>
        我是Home組件
    </div>
</template>

<script>
    import { ref } from 'vue';

    export default {
        setup() {

        }
    }
</script>

<style scoped>
</style>
View Code

About.vue 

<template>
    <div>
        我是About組件
    </div>
</template>

<script>
    import { ref } from 'vue';

    export default {
        setup() {

        }
    }
</script>

<style scoped>
</style>
View Code

(3). 配置路由映射

 A. Home組件配置成直接加載,About組件配置成懶加載,並且將About組件打包后生成的名字配置成 about 。

 B. 通過createRouter創建路由對象,並且傳入routes和Hash模式 

 C. 配置路由默認路徑/,自動跳轉到Home組件

代碼分享:

import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'

const routes = [
    // 默認路徑自動跳轉到Home組件
    {
        path: "/",
        redirect: "/home"
    },
    // 下面匹配規則
    {
        path: '/home',
        name: 'Home',
        component: Home
    },
    {
        path: '/about',
        name: 'About',
        component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
    }
]

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router

(4). 配置主頁面

 在App.vue頁面,利用<router-view />進行路由占位顯示,利用</router-link>進行路由跳轉操作。 

PS:<router-view>的作用,用來占位顯示 <router-link> 鏈接到的組件。

App.vue代碼如下: 

<template>
    <div>
        <div class="nav">
            <router-link to="/home">Home</router-link> |
            <router-link to="/about">About</router-link>
        </div>
        <router-view />
    </div>
</template>

<script>
    import { ref } from 'vue';

    export default {
        setup() {

        }
    }
</script>

<style scoped>
    .nav{
        margin-bottom: 20px;
    }
</style>
View Code

(5). 運行效果 

補充幾個知識點:

1. 路由地址的模式

 有 hash模式 和 history模式,通過下面代碼控制: createWebHashHistory是hash模式,createwebHistory是history模式

import { createRouter, createWebHashHistory, createWebHistory } 
const router = createRouter({
    history: createWebHistory(),
    routes
})

 hash模式的地址形式:http://localhost:8080/#/home

 history模式的地址形式:http://localhost:8080/home

2. <router-link>內質組件的屬性

 (1). to屬性:是一個字符串,或者是一個對象

 (2). replace屬性:設置 replace 屬性的話,當點擊時,會調用 router.replace(),而不是 router.push();

 (3). active-class屬性:設置激活a元素后應用的class,默認是router-link-active;

 (4). exact-active-class屬性:鏈接精准激活時,應用於渲染的 <a> 的 class,默認是router-link-exact-active;

eg: 設置如下代碼,選中后的標簽效果:

<style scoped>
    .router-link-active{
        color: green;
        font-weight: bold;
    }
</style>

 

二. 路由懶加載/打包分析

1. 背景

 當打包構建應用時,JavaScript 包會變得非常大,影響頁面加載:

 如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就會更加高效;

PS:默認運行【npm run build】打包,會生成兩個js文件,app.xxxx.js  和 chunk-vendors.xxxx.js ,app.js存放的是自己寫的代碼,chunk-vendors.js存放的是第三方依賴的代碼。 

2. 實操

 這里可以用webpack的分包知識,Vue Router默認就支持動態來導入組件,從而提高首屏的渲染效率;

 用法:component可以傳入一個組件,也可以接收一個函數,該函數 需要放回一個Promise;而import函數就是返回一個Promise;同時可以指定打包后生成的名字

如下:把About組件通過懶加載的方式進行導入,並且指定打包后生成的名字為about

const routes = [
    // 空路徑自動跳轉到Home組件
    {
        path: "/",
        redirect: "/home"
    },
    // 下面匹配規則
    {
        path: '/home',
        name: 'Home',
        component: Home
    },
    {
        path: '/about',
        name: 'About',
        component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
    }
]

3. 打包分析

  通過【npm run build】進行打包,打包后的文件如下:

 

三. 路由嵌套

1. 何為路由嵌套?

 目前我們匹配的Home、About、User等都屬於底層路由,我們在它們之間可以來回進行切換;但是呢,我們Home頁面本身,也可能會在多個組件之間來回切換:

 比如Home中包括Shops、Monent、Message,它們可以在Home內部來回切換;

 這個時候我們就需要使用嵌套路由,在Home中也使用 router-view 來占位之后需要渲染的組件;

2. 實操

(1). 路由配置文件

  需要在home組件下增加children節點,在里面配置相應的子路由。

核心代碼:

const routes = [
    // 空路徑自動跳轉到Home組件
    {
        path: "/",
        redirect: "/home"
    },
    // 下面匹配規則
    {
        path: '/home',
        name: 'Home',
        component: Home,
        children: [
            //默認顯示
            {
                path: '',
                redirect: '/home/message'
            },
            {
                path: 'message',
                component: () => import('../views/HomeMessage.vue')
            },
            {
                path: 'monent',
                component: () => import('../views/HomeMonent.vue')
            },
            {
                path: 'shops',
                component: () => import('../views/HomeShops.vue')
            }
        ]
    },
    {
        path: '/about',
        name: 'About',
        component: () => import( /* webpackChunkName: "about" */ '../views/About.vue')
    },
    {
        path: '/user',
        name: 'User',
        component: () => import( /* webpackChunkName: "user" */ '../views/User.vue')
    }
]

(2). Home組件

  通過router-link進行子頁面的跳轉,通過router-view進行占位。

<template>
    <div>
        我是Home組件
        
        
        <div class="home">
            <router-link to="/home/message">消息</router-link>
            <router-link to="/home/monent">動態</router-link>
            <router-link to="/home/shops">商品</router-link>
        </div>

        <!-- 路由占位符 -->
        <router-view></router-view>
    </div>
</template>

<script>
    import { ref } from 'vue';

    export default {
        setup() {

        }
    }
</script>

<style scoped>
    .home {
        margin: 40px 0;
    }
    .router-link-active {
        color: green;
        font-weight: bold;
    }
</style>
View Code

(3). 最終效果

 相關地址:http://localhost:8080/home/message   http://localhost:8080/home/monent   http://localhost:8080/home/shops

四. 動態路由剖析

1. 路由的其它屬性

 name屬性:路由記錄獨一無二的名稱;

 meta屬性:自定義的數據

2. 動態匹配規則

 很多時候我們需要將給定匹配模式的路由映射到同一個組件:

 例如,我們可能有一個 User 組件,它應該對所有用戶進行渲染,但是用戶的ID是不同的;

 在Vue Router中,我們可以在路徑中使用一個動態字段來實現,我們稱之為 路徑參數

3. 獲取動態路由的值

(1). 在template模板中

 直接通過:$route.params.xxx來獲取

    <div>
        我是User組件
        <div>我是傳遞過來的id值:{{$route.params.id}}</div>
    </div>

(2). 在created之類的生命周期中

 通過 this.$route.params.xxx 獲取值

created() {
            console.log(this.$route.params);
            console.log(`我是created聲明周期中獲取的值${this.$route.params.id}`)
        },

(3). 在setup()中

 在setup中,我們要使用 vue-router庫給我們提供的一個hook useRoute(注意:不是useRouter);該Hook會返回一個Route對象,對象中保存着當前路由相關的值;

<script>
    import { useRoute } from 'vue-router';

    export default {
        setup() {
            const route = useRoute();
            console.log(`我是setup中獲取的值${route.params.id}`)
        }
    }
</script>

PS:匹配多個參數

4. 配置NotFound頁面 

(1). 作用

 對於那些沒有匹配到的路由,我們通常會匹配到固定的某個頁面,比如NotFound的錯誤頁面中,這個時候我們可編寫一個動態路由用於匹配所有的頁面;

(2). 實操

A. 在所有路由規則的最后,配置如下代碼

{
        // 表示上面所有路徑都匹配不到
        path: "/:pathMatch(.*)",
        component: () => import("../views/NotFound.vue")
    }

B. 在NotFound頁面通過 $route.params.pathMatch 獲取到傳入的參數

<template>
    <div>
        我是NotFound頁面
        <div>{{$route.params.pathMatch}}</div>
    </div>
</template>

C. 輸入地址:http://localhost:8080/user/134543/testkk/3545    ,如下:

PS:

 

 

五. 相關Api

1. 頁面的跳轉push

(1) methods中

 通過this.$router.push實現。 

methods: {
            jumpTo1() {
                this.$router.push('/about');
            }
        }

(2). setup中

 需要引入 userRouter (注:不是userRoute) 這個hooks來實現。

<script>
    import { useRouter } from 'vue-router';

    export default {
        setup() {
            var router = useRouter();
            const jumpTo2 = () => router.push('/user/10086');
            
            return{
                jumpTo2
            }
        }
    }
</script>

在user頁面,通過route.params.id獲取參數值,即為10086

export default {
        created() {
            console.log(this.$route.params);
            console.log(`我是created聲明周期中獲取的值${this.$route.params.id}`)
        },
        setup() {
            const route = useRoute();
            console.log(`我是setup中獲取的值${route.params.id}`)
        }
    }

2. query的方式傳參和接收

頁面傳值代碼

    import { useRouter } from 'vue-router';
    export default {
        setup() {
            var router = useRouter();// 測試傳參2(query的方式)
            const jumpTo3=() => {
                router.push({
                    path: '/home/test2',
                    query: { name: 'ypf', age: 18 }
                })
            };

            return {
                jumpTo3
            }
        }
    }

頁面接收代碼

<script>
    import { useRoute } from 'vue-router';

    export default {
        setup() {
            
            const route=useRoute();
            
            // 1. query類型的接收
            console.log(route.query)
            console.log(route.query.name,route.query.age)

        }
    }
</script>

3. params的方式傳參和接收

跳轉代碼

var router = useRouter();
    // 測試傳參3(params的方式, 必須使用name屬性跳轉,不能用path跳轉)
        const jumpTo4 = () => {
            router.push({
                name: 'test3',
                params: { name: 'ypf', age: 20 }
            });
        };

接收代碼

export default {
        setup() {            
            const route=useRoute();
            
            // 1. param類型的接收
            console.log(route.params)
            console.log(route.params.name,route.params.age)
        }
    }

4. replace替換當前位置

5. 頁面的前進和后退

 

 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM