• 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
      展示router-link的视图

    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.原信息重定向

       meta:{
    required_login: true
    }
    redirect: "/"

    5. demo

    <!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>
        <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    
    </head>
    <body>
    <div id="app">
        <router-link to="/">首页</router-link>
        <router-link to="/course">免费课程</router-link>
        <router-link to="/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 () {
                            // 跳转到登录页面 跳转到登录组件
                            console.log(this.$route)
                            console.log(this.$router)
                            console.log(this.$el)
                            console.log(this.$data)
                            // $route 路由的所有信息
                            // $router VueRouter实例化对象
                            this.$router.push("/login")
                        }
                    }
                }
            },
            {
                path: "/course",
                component: {
                    template: `<div><h1>这是课程组件</h1></div>`
                }
            },
            {
                path: "/login",
                name: 'login',
                component: {
                    template: `<div><h1>这是登录组件</h1></div>`
                }
            },
            {
                path: "/user",
                meta: {
                    required_login: true
                },
                name: 'user',
                component: {
                    template: `<div><h1>这是用户组件</h1></div>`
                }
            },
    
    
        ];
        // 实例化VueRouter对象
        let router = new VueRouter({
            routes: url,
            mode: 'history' //去除url里面的#号
        });
        router.beforeEach(function (to, from, next) {
            console.log(to) // 你去哪里
            console.log(from) // 你从哪里来
            console.log(next) // 你下一步要做什么
            // if(to.path == "/user"){
            //     next("/login")
            // }
            if(to.meta.required_login){
                next("login")
            }
            next()//必须写,调到原来的url
        })
        router.afterEach(function (to, from) {
            // 只用于获取你从哪里来的路由信息
        })
        // 把VueRouter的实例化对象注册到Vue的根实例里
        const app = new Vue({
            el: "#app",
            router: router
        })
    </script>
    
    </body>
    </html>

    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. 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

    <!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}}
    </div>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                name: "明哥"
            },
            methods: {
                init: function () {
                    console.log(123)
                }
            },
            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 相关

      我们在浏览器console里执行命令:
      app.message = "girl"
      我们就触发了update相关的钩子函数,也就是说data里的值被修改会出发update的操作

    5、destroy 相关

      我们在浏览器console里执行命令:
      app.$destroy();
      触发了destroy相关的钩子函数,也就是说组件被销毁
      更改message的值,DOM中的值不变,也就是说DOM元素依然存在只是不受vue控制了

  • 相关阅读:
    CoreThink开发(十三)增加页面加载动画
    CoreThink开发(十二)更改默认出错异常页防止暴露敏感数据
    CoreThink开发(十一)首页控制器判断移动设备还是PC并做相应处理
    CoreThink开发(十)把官方首页轮播替换成HTML5-3D轮播
    CoreThink主题开发(九)使用H-ui开发博客主题之用户个人主页
    CoreThink主题开发(八)使用H-ui开发博客主题之用户登录之前及登录之后
    CoreThink主题开发(七)使用H-ui开发博客主题之新闻资讯正文页面
    centos7搭建postfix邮件服务器
    Kibana插件sentinl实现邮件报警
    kibana-Request Timeout after 30000ms故障解决
  • 原文地址:https://www.cnblogs.com/yidashi110/p/10091813.html
Copyright © 2020-2023  润新知