vue3中watch 与 watchEffect 的用法

1、关于watch和watchEffect的区别

watch- 默认情况是惰性的,也就是说仅在侦听的源数据变更时才执行回调。

watch- 更明确哪些状态的改变会触发侦听器重新运行副作用;

watch- 获取到侦听状态变化前后的值。

————————————————————

watchEffect 不需要手动传入依赖

watchEffect 会先执行一次用来自动收集依赖

watchEffect 无法获取到变化前的值, 只能获取变化后的值

 2、watch

(1)参数说明

source: 可以支持 string,Object,Function,Array; 用于指定要侦听的响应式变量

callback: 执行的回调函数

options:支持 deep、immediate 和 flush 选项。

(2)侦听单个数据源(ref,reactive)

const count= ref(0);

setTimeout(() => {
  count.value++;
}, 1000);

watch(count, (newVal, oldVal) => {
  console.log("新值:", newVal, "老值:", oldVal);
});
import { defineComponent, ref, reactive, toRefs, watch } from "vue";
export default defineComponent({
  setup() {
    const state = reactive({ name: "liu", count: 20 });

    setTimeout(() => {
      state.count++;
    }, 1000);

    // 修改count值时会触发 watch的回调
    watch(
      () => state.count,
      (curCount, preCount) => {
        console.log("新值:", curCount, "老值:", preCount);
      }
    );

    return {
      ...toRefs(state),
    };
  },
});

(3)侦听多个数据

上面两个例子中,我们分别使用了两个 watch, 当我们需要侦听多个数据源时, 使用数组来同时侦听多个源:

watch([() => state.count, count], ([curCount, newVal], [preCount, oldVal]) => {
console.log("新值:", curCount, "老值:", preCount); console.log("新值:", newVal,
"老值:", oldVal); });

(4)侦听复杂的嵌套对象

我们实际开发中,复杂数据随处可见, 比如:

const state = reactive({
  message: {
    id: 7,
    attrs: {
      name: "liu",
      count: "1",
    },
  },
});
watch(
  () => state.message,
  (newType, oldType) => {
    console.log("新值:", newType, "老值:", oldType);
  },
  { deep: true }
);

deep: true 表示开启深度监听。(如果不使用第三个参数deep:true, 是无法监听到数据变化的) immediate: true 无论数据是否发生变化,数据默认执行一次(使watch不为惰性,立即执行回调函数)

(5)stop 停止监听

当 watch在组件的 setup() 函数或生命周期钩子被调用时, 侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。

如果在组件销毁之前我们想要停止掉某个监听, 可以调用watch()函数的返回值,操作如下:

const stopWatch = watch(() => state.message, (newType, oldType) => {
    console.log("新值:", newType, "老值:", oldType);
}, {deep:true});

setTimeout(()=>{
    // 停止监听
    stopWatch()
}, 2000)

3、watchEffect

(1)侦听多个数据源(ref,reactive)

import { defineComponent, ref, reactive, toRefs, watchEffect } from "vue";
export default defineComponent({
  setup() {
    const state = reactive({ name: "liu", count: 20 });
    let count= ref(0)
    watchEffect(() => {
        console.log(state.count);
        console.log(count.value);
      }
    );
    setInterval(() =>{
        state.count++
        count.value++
    },2000)

    return {
        ...toRefs(state)
    }
  },
});

执行结果首先打印一次state.countcount值(默认依赖);然后每隔一秒,打印state.countcount值。 从上面的代码可以看出, 并没有像watch一样需要先传入依赖,watchEffect会自动收集依赖, 只要指定一个回调函数。在组件初始化时, 会先执行一次来收集依赖, 然后当收集到的依赖中数据发生变化时, 就会再次执行回调函数。

(2)watchEffect的flush:作用(post、sync、pre)


 

如果副作用需要同步或在组件更新之前重新运行,我们可以传递一个拥有 flush 属性的对象作为选项(默认为 'post'):

如果没有{ flush:'post' },默认就是先执行监听器,然后更新DOM,此时DOM还未生成,所以是null。--更新DOM,配置flush: 'post'

// 同步运行
watchEffect(
  () => {
    /* ... */
  },
  {
    flush: 'sync',
  }
)

// 组件更新前执行
watchEffect(
  () => {
    /* ... */
  },
  {
    flush: 'pre',
  }
)

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