WEB前端开发学习笔记——Vue中watch的使用

682 阅读2分钟

vue中的watch是一个比较重要的概念,通过他我们可以检测data的变化,下面进行详细的介绍。

watch定义方式如下:

{[key: string]: string | Function | Object  }

即在watch中,

  • 键是一个字符串,它是被观测的对象。
  • 值可以是一个字符串,这个字符串是方法名。
  • 值还可以是一个函数,但不能使用箭头函数的形式,this会出现问题。
  • 值也可以是一个对象,其中包含回调函数可以其他一些选项:比如是否深度遍历。

简单的监听

  • 键是字符串,直接指向观测对象
<body>
<div id="app">
    <input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            num: ''
        },
        watch: {
            num(newVal, oldVal) {
            // 监听 num 属性的数据变化
    		// 作用 : 只要 num 的值发生变化,这个方法就会被调用
    		// 第一个参数 : 新值
    		// 第二个参数 : 旧值,之前的值
                console.log('oldVal:',oldVal)
                console.log('newVal:',newVal)
            }
        }
    })
</script>
</body>

immediate(立即处理 进入页面就触发) 

<body>
<div id="app">
    <input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            num: 1
        },
        watch: {
            num: {
            	// 数据发生变化就会调用这个函数  
                handler(newVal, oldVal) {
                    console.log('oldVal:', oldVal)
                    console.log('newVal:', newVal)
                },
                // 立即处理 进入页面就触发
                immediate: true
            }
        }
    })
</script>
</body>

deep(深度监听) 

对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以不会触发watch。这时我们需要进行深度监听,就需要加上一个属性 deep,值为 true。

<body>
<div id="app">
    <input type="button" value="更改名字" @click="change">
</div>
<script src="vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            food: {
                id: 1,
                name: '冰激凌'
            }
        },
        methods: {
            change() {
                this.food.name = '棒棒糖'
            }
        },
        watch: {
        	// 第一种方式:监听整个对象,每个属性值的变化都会执行handler
        	// 注意:属性值发生变化后,handler执行后获取的 newVal 值和 oldVal 值是一样的
            food: {
                // 每个属性值发生变化就会调用这个函数
                handler(newVal, oldVal) {
                    console.log('oldVal:', oldVal)
                    console.log('newVal:', newVal)
                },
                // 立即处理 进入页面就触发
                immediate: true,
                // 深度监听 属性的变化
                deep: true
            },
            // 第二种方式:监听对象的某个属性,被监听的属性值发生变化就会执行函数
            // 函数执行后,获取的 newVal 值和 oldVal 值不一样
            'food.name'(newVal, oldVal) {
                console.log('oldVal:', oldVal)   // 冰激凌
                console.log('newVal:', newVal)   // 棒棒糖
            }
        }
    })
</script>
</body>

Watch和computed的区别

Watch

watch用于观察和监听页面上的vue实例,当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,那么watch为最佳选择

computed

可以关联多个实时计算的对象,当这些对象中的其中一个改变时都会触发这个属性
具有缓存能力,所以只有当数据再次改变时才会重新渲染,否则就会直接拿取缓存中的数据。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>vue</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
</head>
<body>
    <script>
      var vm = new Vue({
        data: {
          a: 1,
          b: 2,
          c: {
            name: "JohnZhu"
          }
        },
        watch: {
          //值是函数
          a: function (val, oldVal) {
            console.log('new a: %s, old a: %s', val, oldVal)
          },
          //值是方法名
          b: 'someMethod',
 
          // 深度 watcher,检测到变化,并打印出c.name变化前后的结果
          'c.name': {
            handler: function (val, oldVal) { 
              console.log('new c: %s, old c: %s', val, oldVal);
            },
            deep: true
          },
 
          // 报错 必须用c.name,否则在data下不能直接找到name
          // name: function () {
          //   console.log('new c: %s, old c: %s', val, oldVal);
          // }
 
          // 报错,键值必须是一个字符串,所以用引号括起来
          // c.name: {
          //   handler: function (val, oldVal) {
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: true
          // }
 
          // 这里未检测到变化
          // c : {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: false
          // },
         
          // 成功检测到变化 
          c : {
            handler: function (val, oldVal) { 
              console.log('new c: %s, old c: %s', val, oldVal);
            },
            deep: true
          },
 
          // 检测不到变化,因为参数 deep 的默认值是false
          // c : {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          // },
        },
        methods: {
          someMethod: function () {
            alert("b is changed");
          }
        }
      })
      vm.a = 2; // new: 2, old: 1
      vm.b = 666; // alert 666
      vm.c.name = "HTT";
    </script>
</body>
</html>

总结:

  • watch函数的参数中,第一个是改变之前的值,第二个是改变之后的值, 这两个参数非常有用。
  • 这里分别使用了 三种定义函数(或option)的方法。
  • 如果要观察data下一个对象的属性,我们可以使用 '对象.属性' 的方式, 注意: 一定要要引号。
  • 如果改变了一个对象的属性,就必须使用 deep: true, 否则检测不到变化。

转自:
vue中watch的详解
vue中watch的使用