VueRouter和Vue生命周期(鈎子函數)


一、vue-router路由

1、介紹

vue-router是Vue的路由系統,用於定位資源的,在頁面不刷新的情況下切換頁面內容。
類似於a標簽,實際上在頁面上展示出來的也是a標簽,是錨點。
router需要相應的js文件,可到官網下載或者使用CDN: https://unpkg.com/vue-router/dist/vue-router.js
使用Vue需要引入相應的JS文件,可到官網下載或者直接使用CDN:https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js

 

2、路由注冊

1. 定義一個路由匹配規則和路由對應組件的對象

let url = [
    {
        path: "/",  // 路由
        component: {  // 組件:component單數時,代表這個組件就是這個url的唯一組件,因此不需要寫組件名
        }
    }
]

2. 實例化VueRouter對象 並把匹配規則注冊進去

let my_router = new VueRouter({
    routes: url,
    // 路由去掉#
    mode: 'history'
})

3. 把VueRouter實例化對象注冊Vue的根實例

const app = new Vue({
    el: "#app",
    router: my_router
})

4. router-link
  把匹配規則轉成a標簽

5. router-view
  路由的組件顯示的區域

6. demo

<body>
<div id="app">
    <router-link to="/">首頁</router-link>
    <router-link to="/class">班級</router-link>
    <router-view></router-view>
</div>

<script>
    // 定義路由匹配規則和路由對應的組件對象
    let url = [
        {
            path: "/",
            component: {// component單數時,代表這個組件就是這個url的唯一組件,因此不需要寫組件名,直接寫配置信息即可
                template: `<div><h1>你好!這是首頁</h1></div>`
            }
        },
        {
            path: "/class",
            component: {
                template: `<div><h1>這是班級信息</h1></div>`
            }
        }
    ];

    // 實例化VueRouter對象,並把url注冊進去
    let my_router = new VueRouter({
        routes: url,
        // 路由去掉#
        mode: 'history'
    });

    // 把VueRouter實例對象注冊到Vue的根實例里
    const app = new Vue({
        el: "#app",
        router: my_router
    })

</script>
</body>
View Code

 

3、命名路由及參數

1. 注意:要使用命名路由,那么命名路由的router-link里to一定要v-bind,可以簡寫 :to
2. Vue的路由中,路由命名相當於python的路由別名,用name命名
3. 如果路由中需要在路由中加參數,則使用params
4. 如果在路由后面添加?搜索參數,則使用query
5. 要使用這些參數,則用this.$route,route是路由的所有信息
6. $route的參數
  fullPath: "/student/ming?age=38" # 包含?參數的路徑
  hash: ""
  matched: [{…}] # 路由匹配的正則
  meta: {} # 元信息
  name: "student" # 路由別名
  params: {sname: "ming"} # 路由參數
  path: "/student/ming" # 不含?參數的路徑
  query: {age: 38} # ?參數
  __proto__: Object

7. demo

<body>
<div id="app">
    <router-link v-bind:to="{name: 'home'}">首頁</router-link>

    <router-link to="/class?class_id=1">班級</router-link>
    <!--<router-link :to="{name: 'class', query: {class_id: 1}}">班級</router-link>-->

    <!--<router-link to="/student/ming?age=38">用戶</router-link>-->
    <router-link :to="{name: 'student', params: {sname: 'ming'}, query: {age: 38}}">學生</router-link>
    <router-view></router-view>
</div>

<script>
    let url = [
        {
            path: '/',
            name: 'home',
            component: {
                template: `<div><h1>你好!這是首頁</h1></div>`
            }
        },
        {
            path: '/class',
            name: 'class',
            component: {
                template: `<div><h1>這是{{this.$route.query.class_id}}班</h1></div>`
            }
        },
        {   // 在路由中添加參數使用  :name
            path: '/student/:sname',
            name: 'student',
            component: {
                template: `<div>
                        <h1>這是{{this.$route.params.sname}}年齡是{{this.$route.query.age}}</h1>
                        </div>`,
                mounted(){
                    console.log(this.$route)
                }
            }

        }
    ];

    // 實例化VueRouter對象
    let my_router = new VueRouter({
        routes: url,
        mode: 'history'
    });

    // 把VueRouter實例注冊到Vue根實例
    const app = new Vue({
        el: "#app",
        router: my_router,
    })

</script>
</body>
View Code

 

4、手動路由

1. 注意:$route是路由的所有信息,而$router是VueRouter實例化對象
2. $router.push 把這個router對象跳轉到哪里
3. 手動路由的兩種寫法
this.$router.push("/login")
this.$router.push({name:'login', params:{},query: {}})

4. demo

<body>
<div id="app">
    <router-link to="/">首頁</router-link>
    <router-link to="/class">班級</router-link>
    <router-link :to="{name:'login'}">登錄</router-link>
    <router-view></router-view>
</div>

<script>
    // 定義路由匹配規則和路由對應的組件對象
    let url = [
        {
            path: "/",
            component: {
                template: `<div>
                        <h1>你好!這是首頁</h1>
                        <button v-on:click="my_click">點擊跳轉到登錄頁面</button>
                        </div>`,
                methods: {
                    my_click: function () {
                        // $route 路由的所有信息
                        // $router VueRouter實例化對象
                        console.log(this.$route);
                        console.log(this.$router);
                        // push跳轉到登錄頁面
                        // this.$router.push("/login")
                        this.$router.push({name: "login"})
                    }
                }
            }
        },
        {
            path: "/class",
            component: {
                template: `<div><h1>這是班級信息</h1></div>`
            }
        },
        {
            path: "/login",
            name: "login",
            component: {
                template: `<div><h1>這是登錄頁面</h1></div>`
            }
        }
    ];

    // 實例化VueRouter對象,並把url注冊進去
    let my_router = new VueRouter({
        routes: url,
        // 路由去掉#
        mode: 'history'
    });

    // 把VueRouter實例對象注冊到Vue的根實例里
    const app = new Vue({
        el: "#app",
        router: my_router
    })

</script>
</body>
View Code

 

5、路由的鈎子函數

1. 路由鈎子函數:一個路由跳轉到另一個路由(還沒到)的過程中觸發 beforeEach(function (to, from, next) {})
2. 路由鈎子函數:一個路由已經跳轉到了另一個路由后觸發 afterEach(function (to, from) {})
3. 參數: 
  to 你要去哪里
  from 你從哪里來
  next 你接下來要做什么
4. next的參數詳解
  next(function) 一定要調用這個方法來resolve這個鈎子函數。執行效果依賴next方法的調用參數
  next() 什么都不做繼續執行到調轉的路由
  next(false) 中斷當前導航 沒有跳轉 也沒有反應
  next("/") 參數是路徑 調轉到該路徑
  next(error) 如果next參數是一個Error實例 導航終止該錯誤,會傳遞給router.onError()注冊過的回調中

5. demo

<body>
<div id="app">
    <router-link to="/">首頁</router-link>
    <router-link :to="{name: 'class', query: {class_id: 1}}">班級</router-link>
    <router-link :to="{name: 'user'}">用戶</router-link>
    <router-link to="/login">登錄</router-link>
    <router-view></router-view>
</div>

<script>
    let url = [
        {
            path: '/',
            component: {
                template: `<div>
                        <h1>你好!這是首頁</h1>
                        <button @click="my_click">點擊跳轉到登錄頁面</button>
                        </div>`,
                methods: {
                    my_click: function () {
                        this.$router.push("/login")
                    }
                }
            }
        },
        {
            path: '/class',
            name: 'class',
            component: {
                template: `<div><h1>這是{{this.$route.query.class_id}}班的信息</h1></div>`
            }
        },
        {
            path: '/login',
            name: 'login',
            component: {
                template: `<div>
                        <h1>這是登錄頁面</h1>
                        </div>`
            }
        },
        {
            path: '/user',
            name: 'user',
            meta: {
                // 設置元信息
                required_login: true
            },
            component: {
                template: `<div><h1>這是用戶組件</h1></div>`
            }
        }
    ];

    // 實例化VueRouter對象
    let my_router = new VueRouter({
        routes: url,
        mode: 'history'
    });

    // 路由my_router的鈎子函數:一個路由跳轉到另一個路由(還沒到)的過程中觸發
    my_router.beforeEach(function (to, from, next) {
        console.log(to);  // 你要去哪里
        console.log(from);  // 你從哪里來
        console.log(next);  // 你接下來要做什么
        if(to.meta.required_login){
            next('/login')
        }else{
            next();
        }
    });

    // 路由my_router的鈎子函數:一個路由已經跳轉到了另一個路由后觸發
    my_router.afterEach(function (to, from) {
       // 一般只用於獲取你從哪里來的路由信息
        console.log(to);  // 你要去哪里
        console.log(from);  // 你從哪里來
    });

    // 把VueRouter實例注冊到Vue根實例
    const app = new Vue({
        el: "#app",
        router: my_router,
    })

</script>
</body>
View Code

 

6、子路由的注冊

1. 在父路由里注冊children: [{},{}]
2. 在父路由對應的組件里的template里寫router-link router-view
3. redirect:重定向到某個頁面
4. 子路由的path不寫"/"前綴,則會自動跟父級路由拼接
5. 如果寫了"/"前綴,那么path就是你寫的路徑
6. 點擊子路由連接,會觸發其父路由,子路由的template只會顯示在父路由的template里面
7. 子路由可以直接在Vue作用域使用,但還是會觸發它的父路由的template

8. demo

<body>
<div id="app">
    <router-link to="/">首頁</router-link>
    <router-link to="/class">班級</router-link>
    <router-link to="/class/info">班級信息</router-link>
    <router-link :to="{name: 'grade'}">年級</router-link>
    <router-view></router-view>
</div>

<script>
    let url = [
        {
            path: '/',
            component: {
                template: `<div><h1>你好!這是首頁</h1></div>`
            }
        },
        {
            path: '/class',
            component: {
                template: `<div><h1>這是班級</h1></div>`
            }
        },
        {
            path: '/class/info',
            // 路由重定向redirect,進入/class/info,就會重定向到/class/info/grade
            // redirect: {name: 'grade'},
            component: {
                template: `<div>
                        <h1>這是班級詳細信息</h1>
                        <hr>
                        <router-link :to="{name: 'grade'}">所在年級</router-link>
                        <router-link to="/class/class_id">所在班級</router-link>
                        <router-view></router-view>
                        </div>`,
            },
            children: [
                {
                    // 沒寫前綴會直接拼接在父級路由后 path: /class/info/grade
                    path: "grade",
                    // 路由別名
                    name: 'grade',
                    component: {
                        template: `<div><h2>一年級</h2></div>`
                    }
                },
                {
                    // 自己直接寫路由,不會拼接在父級路由后
                    path: "/class/class_id",
                    component: {
                        template: `<div><h2>3班</h2></div>`
                    }
                }
            ],
        },
    ];

    // 實例化VueRouter對象
    let my_router = new VueRouter({
        routes: url,
        mode: 'history'
    });

    // 把VueRouter實例注冊到Vue根實例
    const app = new Vue({
        el: "#app",
        router: my_router,
    })

</script>
</body>
View Code

 

7、命名路由視圖

1. 當我們只有一個<router-view></router-view>的時候,所有內容都展示在這一個面板里面。
如果是content和footer需要同時顯示在不同區域,這就需要對視圖進行命名。
2. 路由中使用components(是復數),{組件名1: 配置信息1, 組件名2: 配置信息2}
3. 在HTML視圖中使用<router-view name="header"></router-view>區分不同的組件
4.也就是說路由的組件:

component(單數)用<router-view></router-view>標簽
components(復數)用<router-view name="組件名"></router-view>標簽

5. demo

<body>
<div id="app">
    <router-link to="/">首頁</router-link>

    <router-link to="/class">班級</router-link>
    <router-link to="/class/info">班級信息</router-link>
    <router-view name="header"></router-view>
    <router-view name="footer" style="position: fixed;bottom: 0"></router-view>
    <router-view></router-view>
</div>

<script>
    let url = [
        {
            path: '/',
            component: {
                template: `<div><h1>你好!這是首頁</h1></div>`
            }
        },
        {
            path: '/class',
            component: {
                template: `<div><h1>這是班級</h1></div>`
            }
        },
        {
            path: '/class/info',
            // components 復數 有多個組件,要寫組件名
            components: {
                header: {
                    template: `<div><h1>這是班級頭</h1></div>`
                },
                footer: {
                    template: `<div><h1>這是班級尾</h1></div>`
                }
            },
        },
    ];

    // 實例化VueRouter對象
    let my_router = new VueRouter({
        routes: url,
        mode: 'history'
    });

    // 把VueRouter實例注冊到Vue根實例
    const app = new Vue({
        el: "#app",
        router: my_router,
    })

</script>
</body>
View Code

 

二、Vue的生命周期及其鈎子函數

1、圖示

 

對比

 

2、demo

beforeCreate         啥也沒有
created                 有數據和事件(方法)、無el

beforeMount         形成虛擬Dom,有el、數據和事件(方法)
mounted               渲染頁面了,有el、數據和事件(方法)

beforeUpdate       數據改變前觸發
updated                數據改變后觸發

beforeDestroy     vue實例銷毀前觸發
destroyed            vue實例銷毀時觸發

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

</head>
<body>
<div id="app">
    {{name}}
    <button @click="my_update">點擊觸發update</button>
    <button @click="my_destroy">點擊觸發destroy</button>
</div>
<script>
    const app = new Vue({
        el: "#app",
        data: {
            name: "明哥"
        },
        methods: {
            init: function () {
                console.log(123)
            },
            my_update: function () {
                this.name = "狗子"
            },
            my_destroy: function () {
                app.$destroy()
            }
        },
        beforeCreate(){
            console.group("BeforeCreate");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        created(){
            console.group("Create");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        beforeMount(){
            console.group("BeforeMount");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        mounted(){
            console.group("mounted");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        beforeUpdate(){
            console.group("BeforeUpdate");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        updated(){
            console.group("updated");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        beforeDestroy(){
            console.group("BeforeDestroy");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        },
        destroyed(){
            console.group("Destroy");
            console.log(this.$el);
            console.log(this.name);
            console.log(this.init);
        }
    })
</script>

</body>
</html>
View Code

 

 

 

 

 

 

3、create 和 mounted 相關

執行上面代碼,可以看到:
  beforecreated :el 和 data 並未初始化
  created:完成了data數據的初始化 el 沒有
  beforeMount:完成了el 和 data的初始化
  mounted:完成了掛載
  也就是說,掛載前的狀態是虛擬DOM技術,先把坑站住了,掛載之后才真正的把值渲染進去

 

4、update 相關

  我們修改了app的data的某個值時,
  我們就觸發了update相關的鈎子函數,也就是說data里的值被修改會觸發update的操作

 

5、destroy 相關

  我們在瀏覽器console里執行命令:
  app.$destroy();
  觸發了destroy相關的鈎子函數,也就是說組件被銷毀
  更改message的值,DOM中的值不變,也就是說DOM元素依然存在只是不受vue控制了

 


免責聲明!

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



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