Vue系列——02-05监听器-watch

120 阅读1分钟

​​​​​本文已参与「新人创作礼」活动,一起开启掘金创作之路。

目录

computed和watch 

使用watch深度监听01

watch深度监听02


watch:在vue中,使用watch来响应数据的变化,监听异步操作异步场景。

{{watchFullName}}无需加()

案例只监听了data中数据的watchFullName的变化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>监听器</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
</head>
<body>
    <!-- watch监听异步操作异步场景监听器后面无需加()
        此案例只监听了data中数据的watchFullName的变化
    -->
    <div id="box">
        <h1>计算属性:computed</h1>
        {{fullName}}

        <h1>方法:methods</h1>
        {{fullName2()}}

        <h1>监听器:watch</h1>
        {{watchFullName}}
        <h1>年龄</h1>
        {{age}}
    </div>
    <script>
        var other = 'This is other';
        var box = new Vue({
            el:'#box',
            data:{
                firstName:'Nan',
                lastName:'Chen',
                age:18,
                watchFullName:'NanChen',
            },
            methods: {
                    fullName2:function(){
                        console.log("调用了fullName,执行了一次方法")
                        fullName2 = this.firstName+this.lastName+","+other;
                        return fullName2;
                    }
                },
            computed: {
                    fullName:function(){
                    console.log("调用了fullName,计算了一次属性")
                    return this.firstName+this.lastName+","+other;
                    }
                },
                watch:{
                    immediate: true,
                    firstName:function(newName,oldName){
                        console.log("lastName触发了watch,newLastName="+newName+",oldLastName="+oldName);
                        this.watchFullName = this.firstName+this.lastName+","+other;
                    },
                    lastName:function(newName, oldName){
                        console.log("lastName触发了watch,newLastName="+newName+",oldLastName="+oldName)
                        this.watchFullName = this.firstName+this.lastName+","+other
                    }  ,
                    
                }
        })
    </script>
</body>
</html>

 这样使用watch时有一个特点,就是当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。

那如何去修改年龄(age) 呢?

可以直接在控制台写

box.age=80

 这里的方法需要重新执行,而watch中没有age属性所以不用在执行一遍

 如何更改other的值?

因为不是box中的元素所以可以直接写other

 

 

这里没有发生任何变化再次修改firstName就会进行重新渲染

原因:是因为我们调用firstName的时候触发了所有的方法包括更改后的watch,上面已经改为了新的值,所以也会跟着改。在实例外的对象,它并不是一修改就有的。而是在修改之后再次修改实例内置对象,它才会更改。

结论:

  1. 使用computed计算了fullName属性,值为firstName+lastName。
  2. 计算属性具有缓存功能,当firstName和lastName都不改变的时候,fullName不会重新计算,比如我们改变age的值,fullName的值是不需要重新计算的。
  3. methods并没有缓存特性,比如我们改变age的值,fullName2()方法会被执行一遍。
  4. 当一个功能可以用上面三个方法来实现的时候,明显使用computed更合适,代码简单也有缓存特性。
  5. 计算属性范围在vue实例内,修改vue实例外部对象,不会重新计算渲染,但是如果先修改了vue实例外对象,在修改vue计算属性的对象,那么外部对象的值也会重新渲染。

computed和watch 

**computed: **计算属性范围在Vue实例的fullName内所管理的firstName和lastName,通常监听多个变量 

watch: 监听数据变化,一般只监听一个变量或数组

使用watch深度监听01

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

	</head>
	<body>
		<div id="app">
             <p>FullName: {{person.fullname}}</p>
             <p>FirstName: <input type="text" v-model="person.firstname"></p>
		</div>
		<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data() {
					return {
						person: {
							firstname: 'Menghui',
							lastname: 'Jin',
							fullname: ''
						}
					}
				},
				methods: {

				},
				computed: {
                   person2(){
					    return JSON.parse(JSON.stringify(this.person));
				   }//解决深度监听新老值同源问题
				},
				watch:{
				   person2:{
					     handler(n,o){
							 console.log(this.person);
							 console.log(n.firstname);
					         console.log(o.firstname);
							
							 /* this.person.fullname = this.person.firstname + this.person.lastname */
						 },
						/* immediate: true, */
						 deep: true  // 可以深度检测到 person 对象的属性值的变化
				   }
				}
			})
		</script>
	</body>
</html>

watch深度监听02

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>

	</head>
	<body>
		<div id="app">
			 <h2>{{sum}}</h2>
			 <button @click="sum++">点击</button>
             <p>FullName: {{person.fullname}}</p>
             <p>FirstName: <input type="text" v-model="person.firstname"></p>
		</div>
		<script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data() {
					return {
						sum:0,
						person: {
							firstname: 'Menghui',
							lastname: 'Jin',
							fullname: ''
						}
					}
				},
				methods: {

				},
				computed: {
                   person2(){
					    return JSON.parse(JSON.stringify(this.person));
				   }//解决深度监听新老值同源问题
				},
				watch:{
				   person2:{
					     handler(n,o){
							 console.log(this.person);
							 console.log(n.firstname);
					         console.log(o.firstname);
							
							 /* this.person.fullname = this.person.firstname + this.person.lastname */
						 },
						/* immediate: true, */
						 deep: true  // 可以深度检测到 person 对象的属性值的变化
				   },
				   sum:{
					   handler(n,o){
						   console.log('sum的值变化了',n,o);
					   }
				   }
				}
			})
		</script>
	</body>
</html>

\