vue - 路由(vue-router)

Vue.js

本章內容:

路由

​ 根據不同的路徑 (錨點) ,顯示不同的頁面 (組件) ,不會刷新整個頁面,,局部更新。

​ 官方地址: https://router.vuejs.org/zh/

引入vue-router
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
vue-router提供的組件
router-view

​ 路由的出口,用於渲染當前路由模板,在含有導航鏈接的頁面都與要進行路由出口,否則路由不起作用。

<router-link to="/Home">首頁</router-link> <!-- 導航鏈接 -->
<router-view></router-view> <!-- 路由出口 -->
router-link

​ 導航鏈接

<router-link to="/Home">首頁</router-link>
  • 標籤屬性

    1. to (必選參數)

      <router-link to="/Login">登錄</router-link>
      <!-- 表示路由的鏈接, 該值可以是字符串, 可也動態綁定數據 -->
      
    2. tag

      <router-link to="/Login" tag="strong">登錄</router-link>
      <!-- tag表示渲染成指定的標籤, 同樣還會監聽點擊, 觸發路由鏈接。默認是<a></a>標籤。 -->
      
定義路由
// 創建`router`實例,傳入`routes`配置。
let router = new VueRouter({
    routes: [
        {
            path: "/index",
            component: { // 每個路由中`component`的應該映射一個組件。
                template: `<h3>首頁</h3>`
            }
        },
        {
            path: "/login",
            component: {
                template: `<h3>登錄</h3>`
            }
        }
    ]
})
new Vue({
    el: "#app",
    router // 將`router`掛載Vue實例中。
})
動態路由

例如,我們有一個 login 組件,對於所有 ID 各不相同的用戶,可以使用動態路由將用戶ID傳入。

<div id="app">
    <router-link to="/index">首頁</router-link>
    <!-- 傳入用戶信息 -->
    <router-link to="/login/1/狗蛋/12345678">登錄</router-link>
    <router-view/> <!-- 路由出口 -->
</div>

// 創建`router`實例,傳入`routes`信息,並定義動態路由。
let router = new VueRouter({
    routes: [
        {
            path: "/index",
            component: {
                template: `<h3>首頁</h3>`
            }
        },
        {
            path: "/login/:userID/:userName/:passWord", // 綁定動態路徑參數,以:進行綁定某些字段。
            component: {
                template: `<h3>{{$route.params}}</h3>`
            }
        }
    ]
})
new Vue({
    el: "#app",
    router // 掛載路由
})
命名路由

​ 命名路由指的是在每一個路由配置上,都必須提供一個name

const Index = {
    template: "..."
}
let router = new VueRouter({
	routes: [
        {
            name: "index", // 提供當前路由配置上的`name`。
            path: "/index",
            component: Index
        }
    ]
})
$router和$route的區別
  • $router爲VueRouter的實例, 是一個全局的路由對象。

  • $route是一個跳轉的路由對象, 每一個路由都有route對象, 是一個局部對象, 包含路由路徑攜帶的參數,以及查詢字符攜帶的參數。

    <div id="app">
        <!-- 查詢參數 -->
        <router-link to="/index?userID=1&userName=大錘&passWord=1314521">首頁</router-link>
        <!-- 動態參數 -->
        <router-link to="/login/33/狗蛋/5211314">登錄</router-link>
        <router-view></router-view> <!-- 路由出口 -->
    </div>
    
    
    let router = new VueRouter({
        routes: [
            {
                path: "/index", // 查詢參數不需要綁定。
                component: {
                    template: `
                        <div>
                            <h3>登錄</h3>
                            <h4>查詢參數爲:{{$route.query}}</h4>
                        </div>
                    `
                }
            },
            {
                path: "/login/:userID/:userName/:passWord", // 綁定動態路徑參數,以:進行綁定某些字段。
                component: {
                    template: `
                        <div>
                            <h3>登錄</h3>
                            <h4>動態參數爲:{{$route.params}}</h4>
                        </div>
                    `
                }
            }
        ]
    })
    new Vue({
        el: "#app",
        router // 掛載`router`實例
    })
    
嵌套路由

路由套路由,<router-view/>內嵌套另一個<router-view/>組件。

<div id="app">
		<router-link to="/index">首頁</router-link>
		<router-link to="/login">登錄</router-link>
		<router-view></router-view>		<!-- 路由出口 -->
	</div>

let router = new VueRouter({
    routes: [
        {
            path: "/index",
            component: {
                template: `
                    <div>
                        <h3>首頁</h3>
                        <router-link to="/index/child1">一入口</router-link>
                        <router-link to="/index/child2">二入口</router-link>
                        <router-link to="/index/child3">三入口</router-link>
                        <router-view></router-view>
                    </div>
				`
            },
            children: [ // 配置index的子路由。
                {
                    path: "child1",
                    component: {
                        template: `<h3>一入口</h3>`
                    }
                },
                {
                    path: "child2",
                    component: {
                        template: `<h3>二入口</h3>`
                    }
                },
                {
                    path: "child3",
                    component: {
                        template: `<h3>三入口</h3>`
                    }
                }
            ]
        },
        {
            path: "/login",
            component: {
                template: `<h3>登錄</h3>`
            }
        }
    ]
})
new Vue({
    el: "#app",
    router: router // 將配置的路由實例掛載Vue實例中。
})
路由重定向

例如我們訪問/a路由,重定向規定爲/b,則當訪問/a就會切換到/b路由。

let router = new VueRouter({
    routes: [
        {
            path: "/", // `/`表示根目錄,`*`會匹配任意路由路徑。
            redirect: "/index" // 定義重定向,如果是根目錄則自動重定向到`redirect`指定的路由。
        },
        {
            path: "/index",
            component: {
                template: "<h3>首頁</h3>"
            }
        },
        {
            path: "/login",
            component: {
                template: "<h3>登錄</h3>"
            }
        }
    ]
})
編程式的導航

​ 在Vue實例內部,你可以通過$router訪問路由實例,因此你可以調用this.$router.push(...)來導航到不同的路由。

​ 或者使用 router.push 方法。這個方法會向 history 棧添加一個新的記錄,所以,當用戶點擊瀏覽器後退按鈕時,則回到之前 的 URL。

routerrouter使router和router功能等效,都可以使用,只不過router是router實例掛載Vue實例之後自動生成的對象。而router是構造函數。

// 實例化router
let router = new VueRouter({
    routes: []
})
new Vue({
    el: "#app",
    methods: {
        routerFn() {
            // $router是`router`實例掛載到Vue中才有的實例對象。
            this.$route.push(...);
            // router實例。 
            router.push(...);
            console.log(router === this.$router); // true,兩種效果等效,都可使用。
        }
    },
    router // 掛載`router`實例
})
  • push
    該方法參數可以是一個字符串路徑,或者是一個敘述地址的對象。例如:

    // 字符串
    this.$router.push("/index");
    // 對象
    this.$router.push({path: "index"});
    // 命名路由,通過路由內配置的`name`值相互綁定,也可實現路由跳轉。
    this.$router.push({name: "index"});
    // params動態路由
    this.$router.push({name: "index", params: {id: 1} }); // -> {id: 1},可以通過$route.params獲取。
    // 查詢參數,URL變成 /index?id=100
    this.$router.push({name: "index", query: {id: 100} }); // -> {id: 100},可以通過$route.query獲取。
    

    如果提供了pathparams就會被忽略,而query不會被忽略。你可以提供路由的name或手寫完整的帶有參數的path

    const Id = '123';
    // 提供了name,有效。
    this.$router.push({name: "index", params: {Id} }); // -> /user/123
    // 提供完整的`path`。
    this.$router.push({ path: `/user/${Id}` }) // -> /user/123
    // 這裏的params不生效。
    this.$router.push({path: "index", params: {Id} });
    
  • go
    這個方法的參數是一個整數,意思是在 history 記錄中向前或者後退多少步,類似 window.history.go(n)

    // 在瀏覽器記錄中前進一步,等同於 history.forward()。
    this.$router.go(1);
    // 後退一步記錄,等同於 history.back()。
    this.$router.go(-1);
    // 前進 3 步記錄
    this.$router.go(3);
    // 如果 history 記錄不夠用,那就默默地失敗唄
    this.$router.go(-100);
    this.$router.go(100);
    
過渡動效

<router-view/>是動態組件,所以我們可以使用<transition/>組件給它添加一些過渡效果。

<transition name="fade">
	<router-view></router-view>
</transition>
單個路由的過渡

上面語法是給所有出口都進行了相同的過渡,如果想給每個路由模板添加各自的效果,可以在<transition/>上定義不同的name

const Bar = {
    template: `
			<transition name="fade">
				<div>...</div>
			</transition>
	`
}
const Foo = {
    template: `
			<transition name="slide">
				<div>...</div>
			</transition>
	`
}
導航守衛

vue-router 提供的導航守衛主要用來通過跳轉或阻止跳轉的方式守衛導航。記住參數或查詢的改變並不會觸發進入/離開的導航守衛

全局前置守衛

​ 使用router.beforeEach來註冊一個全局前置守衛。

let router = new VueRouter({
    routes: [
        // ...
    ]
})
router.beforeEach((to, from, next) => {
    // ...
})

​ 同樣也可以在vue中掛載的路由實例進行註冊導航守衛。

let router = new VueRouter({
    routes: [
        // ...
    ]
})
new Vue({
    el: "#app",
    router,    // ES6語法,與router: router等效
    mounted() {
        // 通過路由實例註冊
        this.$router.beforeEach((to, from, next) => {
            // ...
        })
    }
})
  • 每個守衛方法接受三個參數:

    • to
      即將要進入的目標路由。

    • from
      即將要離開的當前路由。

    • next
      用於允許路由的切換,在路由切換中必須調用next(), 否則鉤子就不會被調用。

      router.beforeEach((to, from, next) => {
          next(); // 進行管道中的下一個鉤子
          next(false); // 中斷當前的導航
          next({path: "/login"}) // 鏈接到指定的路由,與`next("/login")`等效
      })
      
全局後置守衛

​ 使用router.afterEach來註冊一個全局後置守衛,但是它不接收next參數。

router.afterEach((to, from) => {
    // ...
})
前置守衛與後置守衛的區別
  1. 前置守衛在進入前觸發,後置守衛進入後觸發。
  2. 前置守衛接受next回調,後置守衛不接受next回調
路由獨享守衛

​ 在路由配置上直接定義beforeEnter守衛

let router = new VueRouter({
    routes: [
        {
            path: "/index",
            component: Index,
            beforeEnter(to, from, next) {
                // ...
            }
        }
    ]
})
組件內部守衛

​ 在路由組件內直接定義以下路由導航守衛 :

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

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