vue3知识点3vue的生命周期和钩子函数、计算属性、侦听器

982 阅读2分钟

vue3知识点3vue的生命周期和钩子函数、计算属性、侦听器

前言

本节知识点主要是生命周期那几个函数,计算属性和侦听器。

Vm

我们要搞清楚vue的实例对象是谁,vue3中创建vue实例时这个vm就是。然后再连接上视图层,vm.mount("#app")。

const vm = Vue.createApp({
			  data() {
			    return data
			  },
			
			})
vm.mount('#app')

而不是连写的,这样写这个vm不是实例对象。

const vm = Vue.createApp({}).mount('#app')

当把data绑定到vm实例对象上之后,也就是创建了vue实例之后,data的数据也就属于vm对象的了,vm也可以调用data里面的属性。Vm.msg=data.msg


	console.log(vm.msg,"----vm")
	console.log(data.msg,"----data")

注意:vm.msg在钩子函数里报错的话,改this,data 在哪用都可以。

this用于在vue实例里面调用data的数据 this.msg=data.msg

vue的函数中this指向的是vue实例,也就是vm,所以根据上述,this就可以调用data。

视图层
<h4>{{hello}}</h4>

数据层
data={
    msg:'hello'
}

vm实例
const vm=Vue.createApp({})
vm.mount('#app')


	console.log(vm.$data,"---$data")


生命周期钩子函数

在我们创建完vue实例对象后,会执行这几个函数。它们的位置和data平级。

生命周期定义:

浅显说法:data里的变量在什么情况下开始存在,在什么情况下会被从内存删除,失效。

或者做项目时data不是写死的,而是从服务器传过来的。

如果需要从服务器端(数据库)得到数据返回msg的值给前端,所以需要知道什么时候从服务器获取数据:

比如:要在程序刚运行的时候就要获取数据,其实是从Vue框架刚刚建立的时候需要获取数据,即create vue的时候,要写在created里面。

初始化函数created 和mounted

都是在vue框架的实例对象刚刚初始化的时候就执行 ,在实例创建完成之后立即调用。

created

数据层(data)已经和vue实例对象绑定,与视图层并没有绑定, this.$el =null .

也就是这一步:

const app={
    data(){
        return data;
    },
    methods:{}
    ...
    ...
}
const vm=Vue.createApp(app)

从服务器获取数据的时候要在created中完成。

mounted

vue实例对象已经与视图层绑定 this.$el 返回绑定的是标签。

也就是这一步:

vm.mount("#app")

视图层已经渲染完了,不能在这里从服务器获取数据,会出现数据的延迟渲染。

$el: 判断视图层有没有和vm绑定上

el是属于vue实例对象的属性,vm.el能够得到视图层的根结点,vm.$el.getelementby… ,可以判断数据层是不是与视图层绑定上了,有则返回你所绑定视图层的标签 ,没有返回null


	console.log(vm.$el,"---$el")



那el有什么用呢?,vue框架,所以我们不用得到dom标签就可以得到值,但有的时候也需要得到标签做一些事情,那就可以用el获得标签。


created(){
    console.log("created里要做的事") 
    console.log(this.$el,"---$el")
    
    const get_msg="后端获取的"
    this.msg=get_msg

},
    mounted(){
         console.log("mounted------") 
         console.log(this.$el,"---$el")
         console.log(this.$el.getAttribute("id"))
    },

updated

updated的特点:只要数据层的任意一个数据有发生变化 就会执行。不常用,因为有专门侦听指定的数据的变化的方法。

假如所有值都有变化,只侦听数据a的变化,怎么办呢?

只侦听某一个数据发生变化的话,那么就创建侦听器watch.

解绑数据层和视图层unmounted

调用vm实例对象中一个解绑数据层和视图层

解绑 :数据层和视图层 和vue实例对象脱离关系了

vue3 unmounted

vue2里是 destroy

一般项目里是不会解绑的,非要解绑可能是需要做一些数据清理工作。

const vm = Vue.createApp({
			  data() {
			    return data
			  },
			  
			  created(){

			  },
			  mounted(){
			
			  },
			  updated(){
				  
				  
				  console.log("update------")
			  },
			  unmounted(){
				  
				  console.log("解绑")
			  },
			})
			
			vm.mount('#app')

计算属性:

用法:用于简单的操作,定义的时候写在computed里,和函数一样的定义方法,最后一定要有一个返回值。渲染的时候computed里的方法名当成data的属性用{{func}},不用加()。

意思是,可以把computed里的方法,当成data里的属性用。

实际操作:

视图层: <div>{{fun1}}</div>

	computed:{
	  func1(){
	    //是和数据层的哪几个属性有关系的 
		return this.mgs1+this.msg2
		//或者:
	  	const str=this.books.join("-")
			return str

	  }
	}			

通过函数也能实现同样的功能:方法调用的时候要加上()

当它绑定事件的时候就不用加()了。

<div>{{fun2()}}</div>
<input type="text" @click="func2">
methods:{
	fun2(){
		const str=this.books.join("-")
		return str
	}
}

那既然函数也可以实现同样的功能,那还要计算属性干嘛呢?

计算属性和函数的区别

1.渲染的时候:

img

2.多次渲染相同的数据时:

多次渲染相同的计算属性时 ,第一次的计算属性返回的结果会缓存下来 第二次再渲染相同的计算属性的话 如果和上一次相同的话 就直接从缓存中读取数据了 不会再次执行计算属性的过程。只有当计算属性渲染的值发生变化时才会重新计算。

img

可以看出 计算属性不管调用多少次,只执行一次,计算属性有缓存功能,函数每次都会重新进入函数。

​ 所以计算属性的效率更高。

img

3.计算属性的Get和set:赋值和读值

Get:返回给视图的时候是进行操作后把操作后的两个一起返回,和计算属性一样,即读值一样。

Set:在调用的时候需要对data的这两个数据进行赋值,即需要分开操作。

使用场景:所以如果只需要对两个数据一起操作后返回一个值,直接用计算属性。

如果还需要对这两个数据操作完分别赋值,那么用set,get.

img

侦听器 watch

某一个数据变化时侦听数据的变化,数据一旦变化了,要做什么事情。

我这个图这里olddata和newdata写反了。

当msg发生变化时,参数 新数据和旧数据,下面再写逻辑,执行哪个函数。changebooks是我methods里的一个方法。

img

侦听器和计算属性的区别:

计算属性的使用场合:

计算属性是依赖于缓存,数据变化时才重新计算,避免大量重复性调用。

如果数据层中的多个数据(多个商品)影响了其中一个数据(总价格)的话,可以使用计算属性 (缓存数据)

例如每个商品价格的变化会影响总价格。 计算属性都是同步操作。

侦听器的使用场合:

主要用于一个数据影响了多个数据的情况 ,因为它侦听的是一个数据,如果一个数据发生了变化需要做 异步操作,例如 计时器间隔, 数据从server端获取。

例子:

fullName=firstname+lastname,这个案例如果用侦听器做的话需要侦听两个值firstname,lastname,所以需要创建两个函数,一个firstname(),一个lastname,且两个函数里写的内容是一样的,所以不如用计算属性,只用写一次。

image-20211219155547697

侦听器,不要滥用 ,它会对每个侦听的数据 专门开辟一个接口, 性能降低 。 仍然是计算属性最优.

本节操作全部代码(可直接复制):

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="js/vue.global.js"></script>
	</head>
	<body id="app">
		<h4>{{msg}}</h4>
		<button @click='myclick()'>点击我</button><br>
		<h4>{{func1}}</h4><br>
		<!-- 计算属性和函数渲染的区别:属性不用加括号 ,函数有返回值的时候要加()-->
		<!-- 执行的时候计算属性调用多次只进一次方法
				函数调用一次进一次。 -->
		<h4>{{func2}}</h4><br>
		<h4>{{func2}}</h4><br>
		<h4>{{func2}}</h4><br>
		<h4>{{func3()}}</h4><br>
		<h4>{{func3()}}</h4><br>
		<h4>{{func3()}}</h4><br>
		
	</body>
	<script type="text/javascript">
			const data = {
				msg:"hello",
				books:['vue1','vue2','vue3']
				
			}
			
			const vm = Vue.createApp({
			  data() {
			    return data
			  },
			  // 2.生命周期钩子函数:
			  created(){
				console.log("create------") 
				console.log(this.$el,"---$el")//null
				//这里需要从服务器端获取数据,再把数据赋给data
				const get_msg="后端获取的"
				this.msg=get_msg
				
			  },
			  mounted(){
				console.log("mounted------") 
				console.log(this.$el,"---$el")//<h4>...</h4>
			  },
			  updated(){
				  // 只要数据层的数据有发生变化就会调用
				  // 点击按钮,数据层的数据发生变化,进入updated
				  console.log("update------")
			  },
			  unmounted(){
				  //解绑之后,做一些清理工作,把全局定义的变量 null
				  console.log("解绑了")
			  },
			  // 计算属性
			  computed:{
				  func1(){
					  return this.books.length>0?"yes":"no"
				  },
				  func2(){
					  const str=this.books.join("-")
					  console.log("计算属性只一次")
					  return str
					  
				  }
			  },
			  // 观察者:侦听数据的变化:
			  // 点击按钮侦听msg,如果msg的长度>5的时候调用changebooks方法
			  watch:{
				  msg(newdata,olddata){
					  console.log("变化了,watch进了")
					  console.log("旧",olddata,"新",newdata)
					  console.log("长度",newdata.toString().length)
					  if(newdata.toString().length>4){
						  this.changebooks()
					  }
				  }
			  },
			  methods:{
				myclick(){
					//this---执行时所属的对象
					this.msg=Math.random()
				},
				func3(){
					const str=this.books.join("-")
					console.log("函数运行一次执行一次")
					return str
				},
				changebooks(){
					this.books.push("vue444")
					console.log("---我是增加books",this.books)
				}
				
			  }
			})
			// vm才是vue的实例对象
			// 这里一定要分着写
			vm.mount('#app')
	
	// 1.vm.msg=data.msg
	console.log(vm.msg,"----vm")//hello
	console.log(data.msg,"----data")//hello
	
	
	// vm.$data:等同于data
	console.log(vm.$data,"---$data")//{msg: "hello"}
	// $el:你所绑定的根结点的dom元素
	console.log(vm.$el,"---$el")//<h4>{{hello}}</h4>
			
			
		</script>
</html>