《Vue2.0 watch侦听器》

190 阅读1分钟

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

GIF 2022-1-6 10-48-37.gif

```<template>
  <div>
    <!-- watch -->
    侦听搜索框:<input type="text" v-model="mode" />

    <hr />

    侦听复选框:<input type="checkbox" :checked="bool" v-model="bool" />

    <hr />

    侦听计算属性:
    <h3>{{ count }}</h3>
    <button @click="num++">enter your</button>

    <hr />

    <!-- 当然不仅仅可以这么玩,还可以这么玩 -->
    <p>{{ value }}</p>
    <button @click="addWatch()">点击添加侦听</button>

    <hr />

    <!-- 继续升级侦听 -->
    <p>{{ a }}</p>
    <p>{{ b }}</p>
    <button @click="WatchResult()">侦听两个值加起来的结果是否有变化</button>

    <hr />

    <!-- 当然,你还可以移除侦听 -->
    <!-- 上面都是简单数据类型,现在让我们看看复杂数据类型 -->
    <p>Array:{{ arr }}</p>
    <button @click="changeArr()">点击修改</button>
    <span>这里你会发现(数组)原来的值和现有的值相同,因为它们的引用指向同一个对象/数组。Vue
    不会保留变更之前值的副本。</span>

    <hr />

    <!-- 侦听对象需要用到一个配置选项: deep  -->
    <p>Object:{{ obj }}</p>
    <button @click="changeObj()">点击修改</button>
    <span>这里你会发现(对象)原来的值和现有的值相同,因为它们的引用指向同一个对象/数组。Vue
    不会保留变更之前值的副本。</span>

    <!-- 最后还有个immediate配置项,页面加载成功会立即调用该侦听器 -->
  </div>
</template>

<script>
export default {
  name: "IndexPage",
  data() {
    return {
      mode: "",
      bool: true,
      num: 1,
      value: 0,
      a: 1,
      b: 1,
      arr: ["章鱼哥", "海绵宝宝", "派大星", "珊迪"],
      obj: {
        id: 1,
        name: "海伦",
        talk: "你不对劲!",
      },
    };
  },
  computed: {
    count() {
      return this.num;
    },
  },
  watch: {
    mode(newVal, oldVal) {
      console.log("(新值):" + newVal, "(旧值):" + oldVal);
    },
    bool(newVal, oldVal) {
      console.log("(新值):" + newVal, "(旧值):" + oldVal);
    },
    count(newVal, oldVal) {
      console.log("(新值):" + newVal, "(旧值):" + oldVal);
    },
    arr(newVal, oldVal) {
      console.log("(新值):" + newVal, "(旧值):" + oldVal);
    },
    obj: {
      handler(newVal, oldVal) {
        console.dir(newVal, oldVal);
      },
      deep: true,
    },
  },
  methods: {
    addWatch() {
      this.$watch("value", (newVal, oldVal) => {
        //这里有坑点,你得写字符串
        console.log("新值:" + newVal, "旧值" + oldVal);
      });
      this.value++;
    },

    WatchResult() {
      this.$watch(
        () => {
          return this.a + this.b;
        },
        (newVal, oldVal) => {
          console.log("新值:" + newVal, "旧值" + oldVal);
        }
      );
      this.a++;
      this.b++;
    },

    removeWatch() {
      let unwatch = this.$watch(
        () => {
          return this.a + this.b;
        },
        (newVal, oldVal) => {
          console.log("新值:" + newVal, "旧值" + oldVal);
        }
      );
      this.a++;
      this.b++;
      unwatch(); //这里就不做演示了,添加侦听器默认会返回一个取消观察函数,用来停止触发回调
    },

    changeArr() {
      this.arr.push("蟹阿金");
    },

    changeObj() {
      this.obj.talk = "HELLO WORD";
    },
  },
};
</script>