vue学习笔记(二)vue的生命周期和钩子函数

前言

通过上一章的学习,我们已经初步的了解了vue到底是什么东西,可以干什么,而这一篇博客主要介绍vue的生命周期和它常用的钩子函数,如果有学过java的园友可能有接触到在学习servlet的时候学过servlet的生命周期servlet 加载--->实例化--->服务--->销毁,对于vue的而言他也有自己的生命周期,那么一起来看看吧!

本章目标

  • 学会并了解vue的生命周期和钩子函数
  • 学会使用手动挂载和调用事件

vue的生命周期和钩子函数

其实在提到vue的生命周期和钩子函数的时候,有的人认为常用的钩子函数有10个,也有的人认为是8个,无论是10个还是8个对于我而言都是一样的,我们主要讲解8个vue的钩子函数。首先来一波官网的对于vue生命周期的图解


image

这一张图关于vue的生命周期已经讲解的特别到位了,但是光靠这一张图还不足于了解它的生命周期,我们需要实践一下,有句古话说的好,实践是检验道理的唯一标准,介绍一下vue的钩子函数。

image

beforeCreate(实例创建前)

实例组件刚开始创建,元素dom和数据都还没有初始化
应用场景:可以在这加个loading事件

created(实例创建后)

数据data已经初始化完成,方法也已经可以调用,但是dom为渲染,在这个周期里面如果进行请求是可以改变数据并渲染,由于dom未挂载,请求过多或者占用时间过长会导致页面线上空白
应用场景:在这结束loading,还做一些初始化,实现函数自执行

beforeMoute(元素挂载前)

dom未完成挂载,数据初始化完成,但是数据的双向绑定还是{{}},这是因为vue采用了虚拟dom技术。

mouted(元素挂载后)

数据和dom都完成挂载,在上一个周期占位的数据把值渲染进去,一般请求会放在这个地方,因为这边请求改变数据之后刚好能渲染。

beforeUpdate(实例更新前)

只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候就会执行这个周期,如果没有数据改变不执行。

updated(实例更新后)

只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的,beforeUpdated和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和死循环。

beforeDestory(实例销毁前)

实例销毁之前调用,在这一步,实例仍然完全可用。

destory(实例销毁后)

vue实例销毁后调用,调用后,vue实例指示的所有内容都会解除绑定,所有的事件监听器都会被移除,所有的子实例也会被销毁。

实例一

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>vue的生命周期实例一</title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="msg" />
            {{msg}}
        </div>
        <button onclick="destory()">销毁</button>
        <script src="../js/vue.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            const vm=new Vue({
                el:'#app',
                data:{
                    msg:'vue'
                },
                beforeCreate(){
                    console.log('vue实例创建前:'+this.msg+','+this.$el);
                    //    数据data和dom都还没有初始化
                },
                created(){
                    console.log('vue实例创建后:'+this.msg+','+this.$el);
                    //数据dom初始化完成,dom还没有初始化完成
                },
                beforeMount(){
                    console.log('元素挂载前:');
                    console.log(this.$el);
                },
                mounted(){
                    console.log('元素挂载后:');
                    console.log(this.$el);
                },
                beforeUpdate(){
                    console.log('实例更新前');
                    console.log(this.msg);
                    console.log(this.$el);
                },
                updated(){
                    console.log('实例更新后');
                    console.log(this.msg);
                    console.log(this.$el);
                },
                beforeDestroy(){
                    console.log('实例销毁前');
                    console.log(this.msg);
                },
                destroyed(){
                    console.log('实例销毁后');
                    console.log(this.msg);
                }
            });
            function destory(){
                vm.$destroy();
            }
        </script>
    </body>
</html>

结果:


image

image

实例二

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>vue的生命周期实例二</title>
    </head>
    <body>
        <div id="app">
            {{name}}
        </div>
        <button onclick="destory()">销毁实例</button>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            const vm=new Vue({
                el:'#app',
                data:{
                    name:'一只流浪的kk',
                    age:18
                },
                beforeCreate(){
                    console.log('============实例创建前=============');
                    console.log(this.$el);    //undefined
                    console.log(this.$data);//undefined
                },
                created(){
                    console.log('============实例创建后=============');
                    console.log(this.$el);
                    console.log(JSON.stringify(this.$data));
                },
                beforeMount(){
                    console.log('============元素挂载前=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                },
                mounted(){
                    console.log('============元素挂载后=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                },
                beforeUpdate(){
                    console.log('============实例更新前=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                },
                updated(){
                    console.log('============实例更新后=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                },
                beforeDestroy(){
                    console.log('============实例销毁前=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                },
                destroyed(){
                    console.log('============实例销毁后=============');
                    console.log(this.$el);    
                    console.log(JSON.stringify(this.$data));
                }
            });
            function destory(){
                vm.$destroy();
            }
        </script>
    </body>
</html>
image

总结

  • beforeCreate() : 此时$el、data 的值都为undefined,即el 和 data 并未初始化 。
  • create(): 此时可以拿到data的值,但是$el依旧为undefined,即data完成了 数据的初始化,el没有。
  • beforeMounte(): $el的值为“虚拟”的元素节点,dom未完成挂载,数据初始化完成,但是数据的双向绑定还是{{}},这是因为vue采用了虚拟dom技术。
  • mouted(): 数据和dom都完成挂载,在上一个周期占位的数据把值渲染进去,一般请求会放在这个地方,因为这边请求改变数据之后刚好能渲染。


    image

vue实例的手动挂载和调用事件

  • vm.$mount( [elementOrSelector] ) 如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用 vm.$mount() 手动地挂载一个未挂载的实例,学习手动挂载和调用事件之前,我提取了一些vue实例常用的属性和方法,带有前缀 $ 便于与代理的data区分。
  • vm.$el:类型(HTMLElement)挂载元素,Vue实例的DOM根元素;即vm.$el===document.getElementById('节点'),注意:相等的情况必须是实例创建之后才行,也就是created之后。
  • vm.$data:类型(Object),Vue实例观察的数据对象。
  • vm.$props:类型(Object),当前组件接收到的 props 对象。Vue 实例代理了- 对其 props 对象属性的访问。
  • vm.$options:类型(Object),用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处。
  • vm.$parent:类型(Vue实例),父实例,如果当前实例有的话。
  • vm.$root:类型(Vue实例),当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
  • vm.$children:类型(Array(Vue实例)),当前实例的直接子组件。需要注意 children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 。children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
    官网地址https://cn.vuejs.org/v2/api/
    接下来是介绍手动挂载和调用事件的常用方法,共有三个
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')
// 同上
new MyComponent({ el: '#app' })
// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)

示例:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>手动挂载和调用事件</title>
    </head>
    <body>
        <div id="app">
        </div>
        <button onclick="hanlderOne()">手动挂载方式一</button>
        <button onclick="hanlderTwo()">手动挂载方式二</button>
        <button onclick="hanlderThree()">手动挂载方式三</button>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            const vm=new Vue({
                data:{
                    name:'vue'
                },
                template:'<h2>{{name}}</h2>'
            })
            function hanlderOne(){
                //方法一,手动挂载到指定的dom
                vm.$mount("#app");
            }
            function hanlderTwo(){
                //手动挂载,触发编译
                vm.$mount();
                document.getElementById('app').appendChild(vm.$el);
            }
            function hanlderThree(){
                //扩展一个新的vue构造器
                const component=Vue.extend({
                    template:'<h2>{{name}}</h2>'
                });
                const a=new component({
                    data:{
                        name:'vue'
                    },
                    el:'#app'
                })
            }
        </script>
    </body>
</html>

结果:


image

vm.$destroy() 完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器,这个方法我们在示例中有使用过,大家可以查看前面的示例。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容