• 先复习一下vue2的写法,监听map对象,两种写法区别如下:
  data() {
    return {
      people1: {
        name: '小美',	//子属性
        work: '在职',
      },
      people2: {
        name: '小帅',	//子属性
        work: '在职',
      },
    };
  },
  watch: {
    // vue2写法
    people1(value): {
    	// 该写法监听的是people对象引用地址,当改变子属性name的值时,对象的引用地址并没有改变,因此不会监听到变化
        console.log(value);
    },
    people2: {
    	handler(value) {
	    	console.log(value);
	    },
        deep: true, // 会监听孙属性,曾孙属性
    },
  },
  • vue3写法支持使用多个watch函数组合使用,watch第三个参数{immediate, deep},代码如下:
import { defineComponent, reactive, watch, Fragment } from 'vue';
const demo = reactive({
  name: '小王',
  info: {
    name: '',
    work: {
      type: '程序员',
      address: '七宝',
    },
  },
});

export default defineComponent({
  name: 'Testthree',
  data() {
    return {
      year: '2021',
      people: {
        name: '小美',
        work: '在职',
      },
    };
  },
  watch: {
    // // vue2写法,这种写法不能监听除了data之外的变量
    // year(value) {
    //   // 基本用法
    //   console.log(value);
    // },
    // people: {
    //   handler(value) {
    //     console.log(value);
    //   },
    //   deep: true, // 会监听孙属性,曾孙属性
    // },
  },
  mounted() {
    // watch(demo, newValue => {
    //   // 推荐这种,vue3写法支持使用多个watch函数组合使用
    //   //监听整个对象,孙属性变更也会触发
    //   console.log(newValue);
    // });
    // watch(() => demo.name, newValue => {
    //   //注意:此时的watch第一个参数是一个箭头函数。
    //   //监听对象中的某个属性
    //   console.log(newValue);
    // });
    // watch(() => ({ ...demo }), newValue => {
    //   //监听对象中的子属性,孙属性变更不会触发
    //   console.log(newValue);
    // });
    // watch(() => demo, newValue => {
    //   //监听对象中的所有属性,作用和第一种监听整个对象一样
    //   console.log(newValue);
    // }, { deep: true });
    // watch(demo.info, newValue => {
    //   //监听整个对象,孙属性变更也会触发
    //   console.log(newValue);
    // });
    watch([() => this.year, demo], ([v1, v2], [oldName, oldNums]) => {
      //注意:此时的第一个参数是一个数组
      //组合监听,监听对象中的所有属性
      console.log(v1);
      console.log(v2);
    });
  },
  render() {
    return (
      <Fragment>
        <h2>watch监听器的几种写法</h2>
        <div onClick={() => {
          // this.year = '2022';
          // this.people.name = '小帅';
          // this.people = {
          //   name: '小张',
          //   work: '入职',
          // };
          // demo.name = '前段小伙';
          // demo.info.name = 'jack';
          // demo.info= {
          //   name: 'lily',
          //   work: {},
          // };
          demo.info.work.address = '闵行';
        }}>更新</div>
      </Fragment >
    );
  },
});

总之

推荐使用vue3watch监听函数/组合API的写法,按需引入,通过改变第一个参数就可以满足不同对象属性监听深度,还可以使用组合监听优化代码。

补充
问:2023面试题:watch、watchEffect、computed区别
答:从使用参数,场景角度区分
(1)使用参数
①watch,在vue3中以组合api方式使用,3个参数(依赖项,回调,deep),依赖项必填,当依赖项更改时会执行回调,;
②watchEffect,立即执行的一个函数,在初始化时就会调用一次,2个参数(回调,回调触发时机flush),不需要传依赖项,自动收集依赖;
③computed,初始化时就会调用一次,参数为依赖项,依赖项可以是get函数返回计算之后的值(必须),也可以是带有 get 和 set 函数的对象,引用两次,但只会执行最近一次;
(2)场景
①watch,可获取先前值和当前值,监听范围广可监听data之外的响应对象,可监听一个,也可以多个组合监听,注意监听reactive响应对象时deep会失效,支持异步;
②watchEffect,不能获取先前值,但支持异步和取消异步onCleanup,提供停止监听方法(watchEffect的返回值);
③computed,不支持异步,有异步操作时无法监听数据变化,适合一个属性受到多个属性影响,如:购物车商品结算;

Logo

前往低代码交流专区

更多推荐