计算属性和侦听器

45 阅读2分钟

计算属性

计算属性是一种在模板中使用的属性,它会根据其依赖的 data 数据动态计算出一个新的值。

计算属性的值会被缓存,在计算属性的依赖数据未发生改变时再次调用计算属性拿到的会是缓存后的值,只有在它的依赖数据发生改变时才会重新执行计算属性。

计算函数的定义

通过 computed 定义计算属性。

<template>
  <div>
    <!-- 调用计算属性不用添加括号 -->
    {{ count }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      num1: 1,
      num2: 2,
    };
  },
  computed: {
    // 计算属性
    count() {
      // 只要 num1 或 num2 其中一个依赖数据发生改变,就会重新执行 count 计算属性。
      return this.num1 + this.num2;
    }
  }
};
</script>

只要 num1num2 其中一个依赖数据发生改变,就会重新执行 count 计算属性。

对象类型的计算属性

计算属性还可以是拥有 settergetter 函数的对象。

<template>
  <div>
    <p>{{ message }}</p>
    
    <button 
      @click="message === '哦吼' ? message = '啊哈' : message = '哦吼' "
    >
      点击
    </button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: "哦吼"
    };
  },
  computed: {
    // 计算属性
    message: {
      // 计算函数被调用时返回的内容
      get() {
        return this.msg;
      },
      // 当计算属性被赋值时,set 函数会被调用。
      set(val) { // val 是新值。
        this.msg = val;
      }
    },
  },
};
</script>

侦听器

大多数情况下使用计算属性更合适,但是当需要执行异步操作或开销较大的操作时,使用 watch 会更有用。

watch 中指定需要监听的数据源,当数据源发生改变后会自动执行 watch 函数。

<script>
export default {
  data () {
    return {
      msg: "哦吼"  
    }
  },
  watch: {
    msg: function (newVal, oldVal) {
      console.log(newVal, "新值");
      console.log(oldVal, "旧值");
    }
  },
  mounted() {
    setTimeout(() => {
      this.msg = "啊哈";
    }, 2000);
  }
};
</script>

watch 是一个对象,对象中的 key 对应的就是数据源的属性名,而 value 可以是一个 函数 或是 对象

key 必须要和 data 中的 property 一致。

对象形式:

<script>
export default {
  data() {
    return {
      msg: "哦吼",
    };
  },
  watch: {
    msg: {
      handler(newVal, oldVal) { // 监听的回调函数
        console.log(newVal, "新值");
        console.log(oldVal, "旧值");
      },
      deep: true, // 深度监听
      immediate: true // 首次进入自动执行
    },
  },
  mounted() {
    setTimeout(() => {
      this.msg = "啊哈";
    }, 2000);
  },
};
</script>
  • handler 是必选项,数据源发生改变后执行的回调函数。
  • deep 可选项,是否深度监听对象中的属性变化,默认是为 false 的。
  • immediate 可选项,watch 默认是懒执行,只有数据源发生改变后才会执行,设置 immediatetrue 后,在初始化时立即执行回调函数。

vm.$watch

$watch() 函数接收三个参数:

  • 数据源名称
  • 回调函数
  • 配置对象
<script>
export default {
  data() {
    return {
      msg: "哦吼",
    };
  },
  mounted() {
    // 调用 $watch 会返回一个卸载侦听器函数
    const unwatch = this.$watch(
      // 对应数据源的属性名
      "msg", 
      // 回调函数
      (newVal, oldVal) => {
        console.log(newVal, "新值");
        console.log(oldVal, "旧值");
      }, 
      // 配置对象
      {
        deep: true,
        immediate: true
      }
    );
    setTimeout(() => {
      this.msg = "啊哈";
      // 卸载侦听器
      unwatch();
    }, 2000);
  },
};
</script>

使用 $watch 创建监听器默认会返回一个 卸载侦听器函数

computed vs watch

computedwatch 都是 vue 中用于监听数据变化的方式。

computed 用于计算属性,它注重返回的结果,所以必须要有 returncomputed 会监听所有使用到的依赖,基于依赖进行计算并缓存结果,只有在依赖发生改变时重新执行计算。

watch 用于监听数据的变化,watch 注重的是函数执行的过程,监听指定的数据源,在数据源发生改变时执行回调函数。

如果需要监听好几组数据可以使用 compunted,如果只是监听单个数据的变化可以使用 watch