zoukankan      html  css  js  c++  java
  • Vue生命周期和钩子函数及使用keeplive缓存页面不重新加载

    Vue生命周期

    每个Vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期,在这个过程中会有一些钩子函数会得到回调
    Vue生命周期图

    • Vue中能够被网页直接使用的最小单位就是组件,我们经常写的:
     var vm = new Vue({
            el: '#app',
            ......
    }
    

    是根组件,el指定了它挂载到哪里(id为app的元素包裹的部分)
    也可以跟普通组件一样这样写:

     var vm = new Vue({
            ......
    }
    vm.$mount("#app");
    

    也可以跟普通组件一样在里面定义template属性指定模板,比如

    new Vue({
      el: '#app',
      router,
      components: { App },
      template: '<App/>',
      methods:{
        
      }
     
    })
    

    根组件里面可使用子组件,并起一个名字:

     var vm = new Vue({
            ......
    components: {
                'my-components': child
            }
    }
    vm.$mount("#app");
    

    这样就可以在id为app的div中使用名字my-components来引用child组件

    div id="app">
               ......
                <my-components :msg="msg1" v-if="show"></my-components>
               ......
        </div>
    
    • beforeCreate:在实例初始化之后,这时候el 和 data 并未初始化
    • created:实完成了 data 数据的初始化,但Vue 实例使用的根 DOM 元素el还未初始化
    • beforeMount:data和el均已经初始化,el并没有渲染进数据,el的值为“虚拟”的元素节点
    • mounted:此时el已经渲染完成并挂载到实例上

    使用keeplive缓存组件视图

    有时候我们显示页面的时候不需要重新加载,使用上次的缓存页面即可,比如单页面应用使用路由进行页面切换时,再切回来,很多时候并不需要重新加载

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    </head>
    
    <body>
        <div id="app">
            <p>{{message}}</p>
            <keep-alive>
                <my-components msg="hello" v-if="show"></my-components>
            </keep-alive>
        </div>
    </body>
    <script>
        var child = {
            template: '<div><input></input></div>',
            props: ['msg'],
            data: function() {
                return {
                    childMsg: 'child'
                };
            },
            created: function() {
                console.log('child reated!');
            },
            mounted: function() {
                console.log('child mounted!');
            },
            deactivated: function() {
                console.log('component deactivated!');
            },
            activated: function() {
                console.log('component activated');
            }
        };
        var app = new Vue({
            el: '#app',
            data: function() {
                return {
                    message: 'father',
                    show: true
                };
            },
            
            components: {
                'my-components': child
            }
        });
    </script>
    
    </html>
    

    被keeplive包裹的组件会使用缓存,我们可以在input里输入文字
    在控制台控制app.show=false,再app.show=true,可以发现前一次输入的文字还在,说明使用了缓存
    deactivated、activated两个方法只在被keeplive包裹的组件中才会回调,deactivated在组件消失时调用,activated在组件显示时调用

    综合示例

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
        <style>
    
        </style>
    </head>
    
    <body>
        <div id="app">
            <p>{{message}}</p>
            <keep-alive>
                <my-components :msg="msg1" v-if="show"></my-components>
            </keep-alive>
        </div>
    </body>
    
    <script>
        var child = {
            template: '<div>from child: {{childMsg}}</div>',
            props: ['msg'],
            data: function() {
                return {
                    childMsg: 'child'
                }
            },
            beforeCreate: function() {
                debugger;
            },
            created: function() {
                debugger;
            },
            beforeMount: function() {
                debugger;
            },
            mounted: function() {
                debugger;
            },
            deactivated: function() {
                alert("keepAlive停用");
            },
            activated: function() {
                console.log('component activated');
            },
            beforeDestroy: function() {
                console.group('beforeDestroy 销毁前状态===============》');
                var state = {
                    'el': this.$el,
                    'data': this.$data,
                    'message': this.message
                }
                console.log(this.$el);
                console.log(state);
            },
            destroyed: function() {
                console.group('destroyed 销毁完成状态===============》');
                var state = {
                    'el': this.$el,
                    'data': this.$data,
                    'message': this.message
                }
                console.log(this.$el);
                console.log(state);
            },
        };
        var vm = new Vue({
            el: '#app',
            data: {
                message: 'father',
                msg1: "hello",
                show: true
            },
            beforeCreate: function() {
                debugger;
            },
            created: function() {
                debugger;
            },
            beforeMount: function() {
                debugger;
            },
            mounted: function() {
                debugger;
            },
            beforeUpdate: function() {
                alert("页面视图更新前");
    
            },
            updated: function() {
                alert("页面视图更新后");
            },
            beforeDestroy: function() {
                console.group('beforeDestroy 销毁前状态===============》');
                var state = {
                    'el': this.$el,
                    'data': this.$data,
                    'message': this.message
                }
                console.log(this.$el);
                console.log(state);
            },
            destroyed: function() {
                console.group('destroyed 销毁完成状态===============》');
                var state = {
                    'el': this.$el,
                    'data': this.$data,
                    'message': this.message
                }
                console.log(this.$el);
                console.log(state);
            },
            components: {
                'my-components': child
            }
        });
    </script>
    
    </html>
    
    • debugger用于在chrome中加载时自动断点
    • 根组件的调用中:
      beforeCreate执行时,data和el均为undefined
      created执行时,data已经初始化,el为undefined
      beforeMount执行时,data和el均已经初始化,此时el并没有渲染进数据,
      此时用console.log(this.$el);打印el,p元素内容还是{{message}},还没有替换为真实的数据
      el指定组件挂载的地方,如果组件没有定义template,vue就会把el对应元素包裹的块拿出来渲染(比如data数据渲染)后再放回去,el对象可以操作里面的各个html子节点,如果指定了template,就会渲染template再挂载到el里面
      mounted执行时,此时el已经渲染完成并挂载到实例上
    • 加载渲染调用顺序:
      父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->子activated(如果是缓存视图)->父mounted->父activated(如果是缓存视图)
    • 控制根组件更新
      控制台输入vm.msg1 = "123"
      数据变化之前会调用beforeUpdate,更新后调用updated,这两个方法只有在更新数据的时候才调用(包括隐藏或显示组件,不管是不是缓存视图)
    • 控制子组件更新
      vm.$children[0].childMsg = "111"
      只会调用自己的beforeUpdate和updated,跟父组件无关
    • 控制子组件隐藏显示:
      隐藏:
      父beforeUpdate->子deactivated(如果是缓存视图)->父updated
      显示:
      父beforeUpdate->子activated(如果是缓存视图)->父updated
    • 销毁流程
      vm.$destroy()
      父beforeDestroy->子deactivated(如果是缓存视图)->子beforeDestroy->子destroyed->父destroyed
  • 相关阅读:
    Python+Selenium 自动化实现实例Xpath捕捉元素的几种方法
    Python+Selenium 自动化实现实例获取页面元素信息(百度首页)
    Example4_6(用类名调用类方法)
    Example5_2(子类对象的构造方法)
    关键字super
    字符数组中的大小写字母变换/使用对象数组
    参数传值(Example4_7.Example4_8,Example4_9)
    私有变量和私有方法(Example4_15和Example4_16)
    Example4_11(关键字this)
    成员变量(对象共享类变量及常量的用法)Example4_4//Example4_5
  • 原文地址:https://www.cnblogs.com/cowboybusy/p/11432465.html
Copyright © 2011-2022 走看看