彻底理解vue的钩子函数,vue的生命周期理解,什么是vue的生命周期,钩子函数

官方图(官方的图大家总是理解不了):使用vue框架,需要在合适的时机做合适的事情,了解了vue对象的生命周期和钩子函数,才能知道,哪些事情应该咋哪个函数里做。一、vue的生命周期的理解生命周期用人举例说明:生命周期就是一个人的一生,此处我需要说的没有人情一点(哈哈)。从人的出生,到成长,到工作,到死亡,就是人的一生,也叫一个人的生命周期。2….

大家好,又见面了,我是你们的朋友全栈君。

官方图(官方的图大家总是理解不了):

彻底理解vue的钩子函数,vue的生命周期理解,什么是vue的生命周期,钩子函数

        使用vue框架,需要在合适的时机做合适的事情,了解了vue对象的生命周期和钩子函数,才能知道,哪些事情应该咋哪个函数里做。

一、vue的生命周期的理解

  1. 生命周期

用人举例说明:

生命周期就是一个人的一生,此处我需要说的没有人情一点(哈哈)。

从人的出生,到成长,到工作,到死亡,就是人的一生,也叫一个人的生命周期。

     2. 对象的生命周期

在程序开发中,对象的生命周期就是:从对象的创建,到使用对象,到对象的消亡整个过程。

用人和对象进行类比(此处没有人性):

人

程序中的对象

人出生

New对象

人工作(ps:要人的目的就是为了工作,如果一个人不工作,不为国家做贡献,那就不是合格的人,活着没有意义)

使用对象的方法和属性(ps:new的对象的目的就是为了用它,用对象主要就是使用对象的方法和属性)

人死亡(ps:人没有用了,那就“去死吧”)

对象使用完就该消亡了(过河拆桥,不用了,那就不要了。)

3. Vue的生命周期

Vue实例,vue组件实例都是vue对象,也是对象。所以,vue的生命周期和对象的生命周期是同样的道理

二、vue生命周期经历的阶段

生命周期是有不同的阶段的,就像人一样,有幼儿期,童年期,少年期,青年期,中年期,老年期。每个阶段应该做不同的事情,但是每个人做的事情又不尽相同。

Vue对象的生命周期也分不同的阶段,不同的阶段也可以做不同的事情,但是不同的vue(组件)对象在不同的阶段做的事情也不尽相同,所以,每个vue组件的代码不相同。

Vue生命周期经历哪些阶段:

  1. 总体来说:初始化、运行中、销毁
  2. 详细来说:开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、销毁等一系列过程

三、生命周期经历的阶段和钩子函数

  1. 实例化vue(组件)对象:new Vue()
  2. 初始化事件和生命周期 init events 和 init cycle
  3. beforeCreate函数:

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

即此时vue(组件)对象被创建了,但是vue对象的属性还没有绑定,如data属性,computed属性还没有绑定,即没有值。

此时还没有数据和真实DOM。

即:属性还没有赋值,也没有动态创建template属性对应的HTML元素(二阶段的createUI函数还没有执行)

     4. 挂载数据(属性赋值)

包括 属性和computed的运算,

      5. Created函数:

vue对象的属性有值了,但是DOM还没有生成,$el属性还不存在。

此时有数据了,但是还没有真实的DOM

       即:data,computed都执行了。属性已经赋值,但没有动态创建template属性对应的HTML元素,所以,此时如果更改数据不会触发updated函数

       如果数据的初始值就来自于后端,可以发送ajax,或者fetch请求获取数据。

    6. 检查

       1)检查是否有el属性
检查vue配置,即new Vue() 里面的el项是否存在,有就继续检查template项。没有则等到手动绑定调用vm.$mount()

完成了全局变量$el的绑定。

        2)检查是否有template属性

检查配置中的template项,如果没有template进行填充被绑定区域,则被绑定区域的el对象的outerHTML(即整个#app DOM对象,包括<div id=”app” >和</div>标签)都作为被填充对象替换掉填充区域

即:如果vue对象中有 template属性,那么,template后面的HTML会替换$el对应的内容。如果有render属性,那么render就会替换template。

即:优先关系时: render  >  template > el

vue中el属性,template属性,render函数的优先级

7  beforeMount函数:

模板编译(template)、数据挂载(把数据显示在模板里)之前执行的钩子函数

此时 this.$el有值,但是数据还没有挂载到页面上。即此时页面中的{
{}}里的变量
还没有被数据替换

8.模板编译:用vue对象的数据(属性)替换模板中的内容

9. Mounted函数:

模板编译完成,数据挂载完毕

即:此时已经把数据挂载到了页面上,所以,页面上能够看到正确的数据了。

此处虽然也可以发送异步请求,但是,没有created早,所以,会显得比较缓慢,所以,建议,在created里发送请求。

10. beforeUpdate函数:

       组件更新之前执行的函数,只有数据更新后,才能调用(触发)beforeUpdate,注意:此数据一定是在模板上出现的数据,并且改数据值修改前后不一样。否则,不会,也没有必要触发组件更新(因为数据不出现在模板里,数据也没有改变,就没有必要再次渲染)

数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前

11. updated函数:

组件更新之后执行的函数

vue(组件)对象对应的dom中的内部(innerHTML)改变了,所以,叫作组件更新之后

12.  activated函数:keep-alive组件激活时调用

13.  deactivated函数:keep-alive组件停用时调用

14.  beforeDestroy:vue(组件)对象销毁之前。

       在这个生命周期钩子函数里,可以销毁定时器,因为定时器是全局的,属于window对象的,所以,组件销毁时,并不会销毁定时器

15.  destroyed:vue组件销毁后

四、测试代码

<!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>vue生命周期学习</title>
  </head>
<body>
  <div id="app">
    <h1>{
  
  {message}}</h1>
    <h1>count:{
  
  {count}}</h1>
  </div>
  <input id="btn01" type="button" value="测试" />
</body>
<script type="text/javascript" src="js/vue.min.js" ></script>
<script>
  var vm = new Vue({
    el: '#app',
    data: {
      message: 'Vue的生命周期',
      age:2
    },
    computed:{
    	count:function(){
    		return this.age+1;
    	}
    },
//  template:"<p>vue对象中的template的内容</p>",
//  render: function(createElement) {
//      return createElement('h1', 'this is createElement')
//  },
    beforeCreate: function() {
      console.group('------beforeCreate创建前状态------');
      console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
     console.log("%c%s", "color:red","count   : " + this.count); //undefined 
      console.log("%c%s", "color:red","message: " + this.message) 
    },
    created: function() {
      console.group('------created创建完毕状态------');
      console.log("%c%s", "color:red","el     : " + this.$el); //undefined
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
      console.log("%c%s", "color:red","count   : " + this.count); //undefined 
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化
    },
    //完成了el的绑定
    beforeMount: function() {
       console.group('------beforeMount挂载前状态------');
       console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
       console.log(this.$el.innerHTML);    
       console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化  
       console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
    },
    mounted: function() {
      console.group('------mounted 挂载结束状态------');
      console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
      console.log(this.$el);    
      console.log(this.$el.innerHTML);    
      console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
      console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
    },
    beforeUpdate: function () {
      console.group('beforeUpdate 更新前状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el.innerHTML);
      console.log("%c%s", "color:red","data   : " + this.$data.message); 
      console.log("%c%s", "color:red","message: " + this.message); 
    }
    ,
    updated: function () {
      console.group('updated 更新完成状态===============》');
      console.log("%c%s", "color:red","el     : " + this.$el);
      console.log(this.$el.innerHTML);   
      console.log("%c%s", "color:red","data   : " + this.$data); 
      console.log("%c%s", "color:red","message: " + this.message); 
    },
//  beforeDestroy: function () {
//    console.group('beforeDestroy 销毁前状态===============》');
//    console.log("%c%s", "color:red","el     : " + this.$el);
//    console.log(this.$el);    
//    console.log("%c%s", "color:red","data   : " + this.$data); 
//    console.log("%c%s", "color:red","message: " + this.message); 
//  },
//  destroyed: function () {
//    console.group('destroyed 销毁完成状态===============》');
//    console.log("%c%s", "color:red","el     : " + this.$el);
//    console.log(this.$el);  
//    console.log("%c%s", "color:red","data   : " + this.$data); 
//    console.log("%c%s", "color:red","message: " + this.message)
//  }
  });
  
  document.getElementById("btn01").onclick = function(){
  		vm.message="改了";
  }

五、模拟vue的构造函数(部分代码)

myVue.js

class MyVue{
	constructor(obj){
		//默认值
		let defaultObj={
		  data: null,
		  computed:null,
		  watch:null,
		  beforeCreate:function(){
			
		  },
		  created:function(){
			
		  },
		  beforeMount:function(){
			
		  },
		  mounted:function(){
			
		  }
		}
		for(let key in defaultObj){
			obj[key]?this[key]=obj[key]:this[key]=defaultObj[key];
		}
		
		//对象创建完毕已经有this了。
		this.beforeCreate();	
		//挂载数据:
		//1)、把传入的data属性的值赋给this
		if(obj.data){
			for(let key in this.data){
				this[key] = obj.data[key];
			}	
			this.$data = obj.data;//设置全局变量
		}
		//2)、计算属性		
		if(obj.computed){
			for(let key in obj.computed){
				this[key] = obj.computed[key].call(this);
			}
		}		
		//created函数
		this.created();
		//检查是否有el属性
		if(obj.el){
			this.el = $(obj.el);
			this.$el = $(obj.el);//设置全局变量
		}
		//检查是否有template属性
		if(this.template){
			//this.template = obj.template;
//			动态创建template 里所有的html元素
		}
		//beforeMonute
		this.beforeMount();
		//用vue对象的数据(属性)替换模板中的内容
		//1)、替换data中的数据
		let html = this.el.innerHTML;				
		for(let key in this.data){
			//用属性值替换,属性名(页面上用双花括号包起来的)
			html=html.replace(new RegExp("{
  
  {"+key+"}}","g"),this[key]);
		}	
		//2)、替换computed中的数据				
		for(let key in this.computed){
			//用属性值替换,属性名(页面上用双花括号包起来的)
			html=html.replace(new RegExp("{
  
  {"+key+"}}","g"),this[key]);
		}	
		this.el.innerHTML = html;
		
		//mounted函数:
		this.mounted();
	}
	
	addWatch(){
		
	}
	
	//数据双向绑定
	
	//
}

function $(str){//#box .cls  p
	if(str.charAt(0)=="#"){
		return document.getElementById(str.substring(1));
	}else if(str.charAt(0)=="."){
		return document.getElementsByClassName(str.substring(1));
	}else{
		return document.getElementsByTagName(str);
	}
}

html代码:

<body>

  <div id=“app”>

    <h1>{
{message}}</h1>

    <h1>count:{
{count}}</h1>

  </div>

</body>

<script type=“text/javascript” src=“js/myvue.js” ></script>

<script>

  var vm = new MyVue({

    el: ‘#app’,

    data: {

      message: ‘Vue的生命周期‘,

      age:1

    },

    computed:{

        count:function(){

           return this.age+1;

        }

    },

    beforeCreate: function() {

      console.group(‘——beforeCreate创建前状态——‘);

      console.log(“%c%s”, “color:red” , “el     : “ + this.$el); //undefined

      console.log(“%c%s”, “color:red”,“data   : “ + this.$data); //undefined

      console.log(“%c%s”, “color:red”,“message: “ + this.message)

    },

    created: function() {

      console.group(‘——created创建完毕状态——‘);

      console.log(“%c%s”, “color:red”,“el     : “ + this.$el); //undefined

      console.log(“%c%s”, “color:red”,“data   : “ + this.$data); //已被初始化

      console.log(“%c%s”, “color:red”,“message: “ + this.message); //已被初始化

    },

    //完成了el的绑定

    beforeMount: function() {

       console.group(‘——beforeMount挂载前状态——‘);

       console.log(“%c%s”, “color:red”,“el     : “ + (this.$el)); //已被初始化

       console.log(this.$el);

       console.log(this.$el.innerHTML);   

       console.log(“%c%s”, “color:red”,“data   : “ + this.$data); //已被初始化 

       console.log(“%c%s”, “color:red”,“message: “ + this.message); //已被初始化 

    },

    mounted: function() {

      console.group(‘——mounted 挂载结束状态——‘);

      console.log(“%c%s”, “color:red”,“el     : “ + this.$el); //已被初始化

      console.log(this.$el);   

      console.log(this.$el.innerHTML);   

      console.log(“%c%s”, “color:red”,“data   : “ + this.$data); //已被初始化

      console.log(“%c%s”, “color:red”,“message: “ + this.message); //已被初始化

    }   

  })

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126119.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Arm-A53资料「建议收藏」

    2012年10月Cortex-A53推出了市场,它带来了ARMv8指令集,在高能效比、节省面积基础上还有显著的性能提升。目前Cortex-A53已可以授权,ARM多个合作伙伴会在2014年推出相关芯片。开发者、OEM厂商和SoC设计者需要了解的Cortex-A53的几个重要特点如下:1、ARM低功耗/高效率的传承ARM9是ARM历史上授权最多的处理器,有超过250个授权。它树立了一个非常重要的功率/成本平衡的最有效点。基于ARM926的功能手机(Nokia…

    2022年4月13日
  • 如果正确读取SQL Server中的扩展事件?

    如果正确读取SQL Server中的扩展事件?

    2021年11月25日
  • c语言延时函数nop,延时函数怎么写delay

    c语言延时函数nop,延时函数怎么写delay1.c语言延时函数delay,怎么算延时下面是delay函延迟函数里执行的都是空语句,也就是说通过循环执行空语句来达到延迟的目的.每执行一条语句,即使是空语句都要耗费电脑一些处理时间的,就是因为这个,在延迟函数里写一些无关紧要的东西,用来浪费电脑处理时间,从而达到延迟目的。数原型:原型:voidDelay(unsignedintnDelay){unsignedinti,j,k;…

    2022年6月18日
  • VMWare虚拟机桥接模式下设置静态IP实现上网

    VMWare虚拟机桥接模式下设置静态IP实现上网一、虚拟机设置:1.1虚拟机===》设置 1.2选择网络适配器===》桥接模式二、虚拟机网络设置2.1编辑===》虚拟网络编辑器2.2三、设置静态IP3.1 查看我们的PC无线网的默认网关是多少,虚拟机的IP以及网关设置必须与PC无线网网关在同一个网段内才能实现通信3.2修改ifcfg-eth0,注:文件名可能不一样,我的是:ifcf…

    2022年5月22日
  • 云服务器需要备案吗(国内服务器免备案方法)

    国内不需要备案的服云服务器内容精选换一换不想看文字,请直接戳视频链接。可以不做备案吗?根据《互联网信息服务管理办法》等相关规定,使用中国大陆节点服务器开办的网站,必须先办理网站备案,备案成功并获取通信管理局下发的ICP备案号后才能开通访问。根据《互联网信息服务管理办法》等相关规定,使用中国大陆节点服务器开办的网站,必须先办理网站备案,备案成功并获取通信管理局下发的ICP备案号后视频点播不需要购买…

    2022年4月14日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号