VUE的路由(vue-router)

VUE的路由(vue-router)

• 參考網址:https://router.vuejs.org/zh/
• Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,讓構建單頁面應用變得易如反掌
• 路由:一個路徑對應一個組件
• 一個簡單的路由配置需要4步
• 創建組件
• 配置路由映射表
• 註冊路由配置表
• 把路由掛在在根實例上

vue-router的使用方法

• HTML
• router-link:這個標籤是路由的導航,會默認被渲染爲一個a標籤
• router-link裏面可以寫一些屬性: to屬性指定鏈接也就是要跳轉的路由,to屬性和路由映射表的path的屬性值一樣
• tag屬性指定router-link渲染標籤
• router-view: 是路由的出口,路由匹配到的組件將渲染到這個標籤裏,當組件切換時,組件的DOM元素刪除
• JavaScript
• 一個簡單的路由配置需要4步
• 創建組件
• 配置路由映射表
• 註冊路由配置表
• 把路由掛在在根實例上
• vue-router中的方法
• 當每一個被路由渲染出來的組件上有一個$router屬性,在這個屬性的原型上有一些操作路由的方法
• push : 直接跳轉到當前路徑對應的路由上 push(路徑)
• back : 回退到上一次的路由上
• go(number):可以往前可以往後回退後前進幾個

路由的嵌套

• 二級路由不能直接配置到routes,應該找到它對應的以及路由,配置到其children屬性上;
• 在組件路由配置是,對象中有children屬性,屬性值是一個數組,裏面配置了子路由,路由中不需要加父路由路徑地址,同時也不需要加"/",當子路由進行匹配式,會自動加上父路由和/到子路由的前面;
命名路由
• 在配置文件中加入name屬性,然後可以用html的router-link標籤的to屬性匹配路由
    <script>
        // 路由:一個路徑對應一個組件
        // 1.創建組件    
        // 2.配置路由映射表
        // 3.註冊路由映射表
        // 4. 把路由掛載到根實例上; 
        let detail = {
            template:"<div>詳情頁</div>"
        };
        let login = {
            template:"<div>登錄註冊頁</div>"
        };
        
        let home = {
            data(){
                return {
                    con:'首頁'
                }
            },
            methods:{
                goList(){
                    console.log(this);
                  //vue-router中的方法
                    //this.$router.push("/allperson")
                    //this.$router.back()
                    this.$router.go(-1)
                }
            },
            template:"<div>{{con}}<button @click='goList'>去列表頁</button></div>"
        }
        
        let person={
            data(){
                return {
                    con:'個人中心頁'
                } 
            },
            template:"#list"
        }
        
        // 配置路由映射表: 是路由和組件的配對情況
        let routes =[
          {path:"/allhome",component:home,name:"first"},
            {path:"/allperson",component:person,children:[
                {path:"detail",component:detail},
                {path:"login",component:login}
           ]}
        ];
      
        // 註冊映射表
        let router = new VueRouter({
            routes:routes
        })
        
        // 將路由掛載到根實例上
        let vm = new Vue({
            el:"#app",
            data:{
            },
            router
        })
    </script>

路由傳參

動態傳參
• 動態路由:路由傳參;路徑後面是一個:變量;這就是動態路由,也可以叫路由動態傳參;會把id以屬性方式放到$route的params屬性上,屬性值就是路由實際的路徑值 
• 特點
• 代碼量少
• 由於動態路由渲染的是同一個子組件,所以子組件不再銷燬,當然也不再創建,複用了之前的組件,性能高;但是生命週期的鉤子函數也不再執行;
<body>
    <div id="app">
        <router-link to="/home/1">1</router-link>
        <router-link to="/home/2">2</router-link>
        <router-link to="/home/3">3</router-link>
        <router-view></router-view>
    </div>
    <script src="../../node_modules/vue/dist/vue.js"></script>
    <script src="../../node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        let home = {
            template:"<div>這是我喜歡的第{{$route.params.id}}本書</div>"
        }
        const router = new VueRouter({
            routes: [{path:"/home/:id",component:home}]
        })
        let vm = new Vue({
            el:"#app",
            data(){
                return {
                }
            },
            router
        })
    </script>
</body>
</html>
query傳參
• 在跳轉網頁時執行一個方法,使用push方法,並傳一個參數,可以在跳轉網頁的$route.query中獲得
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <router-link to="/home">1</router-link>
        <router-link to="/list">2</router-link>
   
        <router-view></router-view>
    </div>
    <script src="../../node_modules/vue/dist/vue.js"></script>
    <script src="../../node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        let home = {
            methods: {
                goList(){
                    this.$router.push({path:'/list',query:{id:100}})
                }
            },
            template:"<div>首頁<button @click='goList'>去列表</button></div>"
        }
        let list={
            created(){
                //let id = this.$route.query.id;
                console.log(this.$route.query.id);
            },
            template:"<div>列表頁</div>"
        }
        const router = new VueRouter({
            routes: [
                {path:"/home",component:home,name:"first"},
                {path:"/list",component:list,name:"second"}
            ]
        })
        let vm = new Vue({
            el:"#app",
            data(){
                return {
                }
            },
            router
        })
    </script>

params方法傳參
• 使用params必須得在to屬性中用name屬性
    <div id="app">
        <router-link :to="{name:'first'}">1</router-link>
        <router-link :to="{name:'second'}">2</router-link>
   
        <router-view></router-view>
    </div>
    <script src="../../node_modules/vue/dist/vue.js"></script>
    <script src="../../node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        let home = {
            methods: {
                goList(){
                    this.$router.push({name:"second",params:{id:500}})
                }
            },
            template:"<div>首頁<button @click='goList'>去列表</button></div>"
        }
        let list={
            created(){
                console.log(this.$route.params.id);
            },
            template:"<div>列表頁</div>"
        }
        const router = new VueRouter({
            routes: [
                {path:"/home",component:home,name:"first"},
                {path:"/list",component:list,name:"second"}
            ]
        })
        let vm = new Vue({
            el:"#app",
            data(){
                return {
                }
            },
            router
        })
    </script>

命名視圖

• 有時候想同時 (同級) 展示多個視圖,而不是嵌套展示,例如創建一個佈局,有 sidebar (側導航) 和 main (主內容) 兩個視圖,這個時候命名視圖就派上用場了。
• 沒有name屬性,會顯示屬性爲default的組件

redirect 路由重定向

• 在配置路由中可以用redirect將路由路徑重新定向
• 在配置路由中可以用redirect設置默認展示的組件
• redirect可以用名字設置,也可以用路徑設置
• / 代表初始頁,*代表全部報錯的網頁
<body>
    <div id="app">
        <router-link to="/home" tag="button">首頁</router-link>
        <router-link to="/list" tag="button">列表頁</router-link>
        <router-view></router-view>
    </div>
    <script src="node_modules/vue/dist/vue.js"></script>
    <script src="node_modules/vue-router/dist/vue-router.js"></script>
    <script>
        let home = {
            template: "<div>首頁內容</div>"
        };
        let list = {
            template: "<div>列表頁內容</div>"
        };
        let found = {
            template: "<div>頁面404</div>"
        };
        // redirect: 重定向
        // 1. routes:[{path:"/a",redirect:"/home"}]
        // 2. routes:[{path:"/a",redirect:{name:"路由名字"}}]
        let routes = [{ path: "/", component: home }, { path: "/home", component: home }, { path: "/list", component: list }, { path: "/a", component: found }, { path: "*", redirect: "/home" }];
        let router = new VueRouter({
            routes
        });
        let vm = new Vue({
            el: "#app",
            router
        })
    </script>

路由的導航守衛

• 導航守衛:當切換導航時,會默認調用一些鉤子函數,那麼這些鉤子函數就是導航的守衛;可以在進入這個導航或者離開這個導航時,在鉤子函數中做一些事情
• 參數或查詢的改變並不會觸發進入/離開的導航守衛(比如動態傳參)
• 如果全部的鉤子函數都執行完了,那麼導航的狀態就是confirmed(確定的)
• 切換到另一個組件,組件是會銷燬的
全局守衛
全局前置守衛(beforeEach)
• 全局的前置鉤子函數,只要切換組件,就會執行
• 這個鉤子函數可以用來寫用戶權限的校驗
• 這個鉤子函數有三個參數,第一個參數(一般寫作to)爲即將要進入的目標路由對象(到哪去),第二個參數(一般寫作from)爲當前導航要離開的路由(從哪來),第三個參數(一般寫作next)爲下一步,只有執行了第三個參數,纔會繼續執行下一個鉤子函數
• 第三個參執行的不同情況
• next() :進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
• next(false) : 中斷當前的導航。如果瀏覽器的URL改變了(可能是用戶手動或者瀏覽器後退按鈕),那麼URL地址會重置到from(第二個參)路由對應的地址
• next('/')或者next({path:'/'}) :跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向next傳遞任意位置的對象,且允許設置諸如replace:true、name:'home'之類的選項以及任何用在router-link的to或router.push中的選項
• next(error) : 如果傳入next的參數是一個error實例(報錯信息),則導航會被終止且該錯誤會被傳遞給router.onError()註冊過的回調
全局解析守衛(beforeResolve)
• 全局解析守衛在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之後,解析守衛會被調用
• 參數與全局前置守衛相同
全局後置鉤子函數(afterEach)
• 全局後置鉤子不會接受next函數頁不會改變導航本身,是路由切換以後執行的鉤子函數
• afterEach只有前兩個參
路由獨享的守衛(beforeEnter)
• 路由獨享守衛在路由配置上定義,在beforeEach和beforeRouteUpdate後執行
• 參數和beforeEach相同
組件內的守衛(在路由組件內定義)
beforeRouteEnter
• 這個鉤子函數在進入路由組件,導航被確定之前調用
• 這個函數的this爲window,因爲當beforeRouteEnter執行前,組件實例還沒有被創建。但是可以通過傳一個回調給next來訪問組件實例。在導航被確認的時候執行回調,並且把組件實例作爲回調方法的參數(一般寫作vm)
• 只有beforeRouteEnter支持給next傳回調
• 參數和beforeEach相同
beforeRouteUpdate
• 在當前路由改變,但是該組件被複用時調用(如動態參數)
• 可以訪問組件實例this
• 當beforeRoute執行的時候,只有三個全局鉤子函數執行,其餘的鉤子函數都不執行(具體看例子)
• 參數和beforeEach相同
beforeRouteLeave
• 導航離開該組件對應路由時調用
• 可以訪問組件實例this
• 這個離開守衛通常用來禁止用戶在還未保存修改前突然離開。該導航可以用next(false)來取消
• 參數和beforeEach相同

完整的導航解析流程

  1. 導航被觸發
  2. 在失活的組件裏調用離開守衛beforeRouteLeave
  3. 調用全局的beforeEach守衛
  4. 在重用的組件裏調用beforeRouteUpdate守衛(2.2版本+)
  5. 在路由配置裏調用beforeEnter
  6. 解析異步路由組件
  7. 在被激活的組件裏調用beforeRouteEnter
  8. 調用全局的beforeResolve守衛(2.5版本+)
  9. 導航被確認
  10. 調用全局的afterEach鉤子
  11. 觸發DOM更新
  12. 用創建好的實例調用beforeRouteEnter守衛中傳給next的回調函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章