Vue面试之watch与computed的区别

Vue中watch与computed的区别

最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容,会不断进行整理~

watch与computed作为Vue中两个处理响应式数据的选项,都用来监听数据变化并执行相应的逻辑,在具体使用时会存在区别:

watch

watch用于监听指定的数据变化并执行相应的回调函数,它有两种写法:

对象形式

javascript 复制代码
watch: {
    shops: {
      handler(oldValue, newValue) {
        // 写一些逻辑,当shops参数发生变化时就会执行
      }
    },
    visible: {
      handler(oldValue, newValue) {
        // 写一些逻辑,当visible参数发生变化时就会执行
      }
    }
  },

当需要设置深层监视时(如要监视一个对象时),则需要开启deep属性:

javascript 复制代码
watch: {
    shops: {
      handler(oldValue, newValue) {
        // 写一些逻辑,当shops参数发生变化时就会执行
      },
      deep: true
    }
  }

当需要在初始时立即执行监听回调函数时,需要设置immediate属性:

javascript 复制代码
watch: {
    shops: {
      handler(oldValue, newValue) {
        // 写一些逻辑,当shops参数发生变化时就会执行
      },
      immediate: true
    }
  }

当不需要深层监视或立即监听时,就可以通过如下简单方式:

javascript 复制代码
  watch: {
    shops(oldValue, newValue) {
      // 写一些逻辑,当shops参数发生变化时就会执行
    },
    visible(oldValue, newValue) {
      // 写一些逻辑,当visible参数发生变化时就会执行
    }
  },

vm.$watch方式

该种方式适合对Vue实例进行监听,语法如下:

javascript 复制代码
vm.$watch(
  expression, // 被观察的表达式,可以是一个函数或者一个字符串
  callback,   // 数据变化时的回调函数
  options     // 选项,可选
);
  1. expression为要观察的表达式,它可以是一个函数,也可以是一个字符串。如果是一个函数,则该函数的返回值将被用作观察的对象,如果是一个字符串,则用于访问实例上的属性;
  2. callback即回调函数,接收两个参数:oldValue和newValue;
  3. options为配置对象,可用于设置是否深度监视(deep)和是否立即监视(immediate);
javascript 复制代码
const vm = new Vue({
// vm 即为创建的vue实例
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  created() {
    // 使用 $watch 监视 message 的变化
    vm.$watch(
      'message',
      (newVal, oldVal) => {
        console.log(`message 发生变化:${oldVal} -> ${newVal}`);
      },
      {
        deep: true,
        immediate: true
      }
    );

    // 修改 message,触发回调函数
    this.message = 'Updated Message';
    // 控制台输出:message 发生变化:Hello, Vue! -> Updated Message
  }
});

computed

computed用于创建 基于响应式数据计算而来的属性 ,该属性可以在模板中直接使用,只有当相关响应式数据发生变化 时才会重新计算,computed选项相当于对数据的一种加工

javascript 复制代码
computed: {
  // 基于data中的属性计算得到
  fullName() {
  // 在firstName或lastName发生变化时会自动计算
    return this.firstName + ' ' + this.lastName;
  },
  // 基于其他computed属性计算得到
  // 在fullName发生变化时会自动计算
  reversedFullName() {
    return this.fullName.split('').reverse().join('');
  }
}

二者区别

相同点

① 二者都是基于Vue的依赖收集机制

② 都是由被依赖的变化触发,从而进行处理计算

不同点

① 时机上,computed从首次被赋值时就被计算 ,而watch不会,需要设置immediate: true才能立即监听

② 性能上,computed会自动进行diff计算,若所依赖项未发生变化,则会从缓存中取值;而watch在每次监听的值发生变化的时候都会执行回调。computed的性能会高

从源码看计算属性:

computed会创建一个计算属性watcher,这个watcher(lazy:true)不会立即执行;通过Object.defineProperty将计算属性定义到实例上;当用户取值时会触发getter,拿到计算属性对应的watcher,看dirty是否为true,如果为true则求值;并且让计算属性watcher中依赖的属性收集最外层的渲染watcher,可以做到依赖的属性变化了,触发计算属性更新dirty并且触发页面更新;如果依赖的值没有发生变化,则采用缓存。

③ 写法上,computed必须要有返回值 ,而watch不用;

④ 异步上,computed不支持异步,watch支持异步 ,支持在回调函数上引入异步方法

⑤ 是否能与data中的属性命名重复, watch必须要监视在data中定义过的属性,computed则不能与data中的属性命名重复

在具体的应用场景下,一般而言,当一个属性受多个属性影响的时候,使用computed,当需要监测一个属性的变化对其它属性的影响时,使用watch

相关推荐
Linux-lucky8 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
风骏时光牛马10 小时前
生成一个移动端标题,只需要一个标题,不需要其他的任何文本。
前端
IT_陈寒10 小时前
Redis雪崩把我坑惨了,这是5年经验的教训
前端·人工智能·后端
SameX10 小时前
HarmonyOS ArkUI List 的侧滑删除 用 ListItem 的 swipeAction + endIcon 的做法
前端
usdoc文档预览13 小时前
USDOC系列之PPT文件在线编辑-VUE前端实现在线浏览器在线编辑PPT文档
前端·vue.js·编辑器·office365·ppt在线编辑·office文件在线编辑·文件在线编辑
Java小卷13 小时前
面向 schema 编程,轻松搞定 Element 虚拟化表格复杂应用场景
vue.js·低代码·element
用户27050777252413 小时前
Agent 调工具卡住?3 种超时与取消策略实测对比
前端
LuHang14 小时前
我一行代码没写,把领导派的活做成了公司内部系统😭
前端
明月_清风14 小时前
Meta 开源了一个 AI Native 组件库:Astryx,150+ React 组件,专为 AI Agent 而设计
前端·人工智能·ai编程
仨孩子的爹14 小时前
Lodop、hiprint 与 vue-print-designer:打印控件选型对比
vue.js