vue-watch监听器

1. 概述

watch是 vue 中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作。

Vue官网很明确的建议我们这样使用watch侦听属性:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

2. 用法

watch: {
   监听的属性: {
      handler(数据改变后新的值, 数据改变前旧的值) {
         编写处理逻辑
      }
   }
}

3. 监听基本类型

<template>
  <div>
    <div>
      <input type="text" v-model="something">
    </div>
  </div>
</template>
<script>
export default {
    data() {
        return {
            something: ""
        }
    },
    watch: {
        "something": {
            handler(newVal, oldVal) {
                console.log("新的值:" + newVal);
                console.log("旧的值:" + oldVal);
                console.log("hellow  world");
            }
        }
    }
}
</script>

输入框中输入1、2 , 效果图如下:

vue-watch监听器_第1张图片

还可以 简写 如下:

watch: {
    "something"(newVal, oldVal)  {
        console.log("新的值:" + newVal);
        console.log("旧的值:" + oldVal);
        console.log("hellow  world");
    }
}

4. 监听复杂类型(数组、对象)中的某个属性

<template>
  <div>
    <div>
      <input type="text" v-model="obj.field1">
    </div>
  </div>
</template>
<script>
export default {
    data() {
        return {
            something: "",
            obj: {
                field1: "",
                field2: ""
            }
        }
    },
    watch: {
        "obj.field1"(newVal, oldVal)  {
            console.log("新的值:" + newVal);
            console.log("旧的值:" + oldVal);
            console.log("hellow  world");
        }
    }
}
</script>

输入框中输入1、2 , 效果图如下:

vue-watch监听器_第2张图片

5. 监听复杂类型

当需要监听一个对象的变化时,普通的 watch 方法无法监听到对象内部属性的变化,可以设置深度监听 deep: true,当对象的属性较多时,每个属性的变化都会执行 handler。

<template>
  <div>
    <div>
      <input type="text" v-model="obj.field1">
    </div>
  </div>
</template>
<script>
import { stringifyQuery } from "vue-router";

export default {
    data() {
        return {
            something: "",
            obj: {
                field1: "",
                field2: ""
            }
        }
    },
    watch: {
        "obj": {
            handler(newVal, oldVal)  {
                console.log("新的值:" + newVal);
                console.log("旧的值:" + oldVal);
                console.log("hellow  world");
            },
            deep: true
        }
    }
}
</script>

输入框中输入1、2 , 效果图如下:

vue-watch监听器_第3张图片

vue 中用 console.log 直接打印对象显示 [object Object],使用 console.log(JSON.stringify(obj)),能把对象以 json 格式输出。

watch: {
    "obj": {
        handler(newVal, oldVal)  {
            console.log("新的值:" + JSON.stringify(newVal));
            console.log("旧的值:" + JSON.stringify(oldVal));
            console.log("hellow  world");
        },
        deep: true
    }
}

vue-watch监听器_第4张图片

⚠️但是,结果发现旧的值和新的值一样,为什么呢?

对于引用类型,赋值指向是地址,地址指向堆区存储的值,所以新旧值一样,换句话说就是指向堆的同一个空间,拷贝的是地址,值也是跟着变的,一旦改变拷贝对象中某个变量的值 原始对象也会被改变;

✨解决方案:

利用深拷贝,会创建出一个新的地址指向新的空间。属性发生改变时,跟原始对象值互不干扰(这里运用了computed计算属性的暂缓特性来赋值)

<template>
  <div>
    <div>
      <input type="text" v-model="obj.field1">
    </div>
  </div>
</template>
<script>
export default {
    data() {
        return {
            something: "",
            obj: {
                field1: "",
                field2: ""
            }
        }
    },
    computed: {
        newObj() {
            return JSON.stringify(this.obj);
        }
    },
    watch: {
        "newObj": {
            handler(newVal, oldVal)  {
                console.log("新的值:" + JSON.stringify(newVal));
                console.log("旧的值:" + JSON.stringify(oldVal));
                console.log("hellow  world");
            },
            deep: true
        }
    }
}
</script>

vue-watch监听器_第5张图片

6. immediate的用法和作用

immediate设置为 true,页面进来就会立即执行监听。

watch: {
    "newObj": {
        handler(newVal, oldVal)  {
            console.log("新的值:" + JSON.stringify(newVal));
            console.log("旧的值:" + JSON.stringify(oldVal));
            console.log("hellow  world");
        },
        deep: true,
        immediate: true
    }
}

vue-watch监听器_第6张图片

进入页面,立即执行监听。

7. VUE3 中的 Watch 用法

VUE2 代码:

watch: {
    nums () {},
    'demo.name' () {}
}

VUE3 代码:

watch(nums, () => {})
watch(() => demo.name, () => {})

详细参考:
VUE3 中的 Watch 详解

你可能感兴趣的:(Vue,vue.js)