美文网首页
(八)观察者 - watch

(八)观察者 - watch

作者: Mr_莫言之 | 来源:发表于2020-10-17 19:01 被阅读0次
本章将介绍的是Vue3.x中的观察者watch,区别于Vue2.x,采用了函数的模式实现

1、概述:Vue2.x中的响应式变量监听,在Vue3.x中以方法的形式使用
2、使用:由vue提供,按需引入:import { watch } from 'vue';
3、监听单一数据

 import { ref, reactive, computed, watch } from 'vue';
setup(props) {
    // ref
    const age = ref(20);
    watch(() => age.value, (nv, ov) => { ... });
    
   // reactive
   const product = reactive({ name: '饮料', count: 1 });
   watch(() => product.count, (nv, ov) => { ... }); 
   
   // props
   watch(() => props.msg, (nv, ov) => { ... }); 
   
   // computed
   const userAge = computed(() => `今年${age.value}岁了!`);
   watch(() => userAge.value, (nv, ov) => { ... }); 
}

4、监听对象

import { ref, reactive, watch } from 'vue';
setup(props) {
    // ref
    const user = ref({ name: 'zhang_san', age: 20 });
    // 字面量引发的监听触发: user.value = { ... };
    watch(() => user.value, (nv, ov) => { ... });
    // 如果使用 user.value.age = 30这种方式去修改user的age值; 将不会触发上面的监听,需要使用watch的第三个参数(深度监听),且触发监听后的nv===ov true
    watch(() => user.value, (nv, ov) => { ... }, { deep: true });
    // 如果我们只需要监听name的值,那么
    watch(() => user.value.name, (nv, ov) => { ... });
    
   // reactive
   const reactiveData = reactive({ user: { name: 'zhang_san', age: 20 } });
    // 字面量引发的监听触发: reactiveData.user = { ... };
    watch(() => reactiveData.user, (nv, ov) => { ... });
    // 如果使用 user.user.age = 30这种方式去修改user的age值,将不会触发监听,需要使用watch的第三个参数(深度监听),且触发监听后的nv===ov true
    watch(() => reactiveData.user, (nv, ov) => { ... }, { deep: true });
    // 如果我们只需要监听name的值,那么
    watch(() => reactiveData.user.name, (nv, ov) => { ... });
}

5、监听数组

import { ref, reactive, watch } from 'vue';
setup(props) {
   // ref
   const user = ref([
      { name: 'zhang_san', age: 10 },
      { name: 'li_si', age: 10 }
   ]);
   // 字面量引发的监听触发: user.value = [ ... ];
   watch(() => user.value, (nv, ov) => { ... });
  // 如果使用数组的操作方法(如:push())或者user.value[0].age = 20这类操作去修改数组某项的属性值,将不会触发监听,也需要使用深度监听模式,且触发监听后的nv===ov true
  watch(() => user.value, (nv, ov) => { ... }, { deep: true });
  
  // reactive
  const reactiveData = reactive({
    user: [
      { name: 'zhang_san', age: 10 },
      { name: 'li_si', age: 10 }
   ]
  });
  // 字面量引发的监听触发: user.user = [ ... ];
  watch(() => reactiveData.user, (nv, ov) => { ... });
  // 如果使用数组的操作方法(如:push())或者user.value[0].age = 20这类操作去修改数组某项的属性值,将不会触发监听,也需要使用深度监听模式,且触发监听后的nv===ov true
  watch(() => reactiveData.user, (nv, ov) => { ... }, { deep: true });
}

6、监听多个数据

import { ref, reactive, computed, watch } from 'vue';
setup(props) {
    const age = ref(20);
    const user = ref({ name: 'zhang_san', age: 20 });
    
    watch([() => age.value, () => user.name], ([newAge, newName], [oldAge, oldName]) => { ... });
}

7、终止监听

import { ref, watch } from 'vue';
const age = ref(20);
// watch监听会返回一个方法
const stop = watch(age, (nv, ov) => { ... });
// 当调用此方法后,该监听就会被移除
stop();

8、清除watch中无效的异步任务

<template>
  <div>
    <input type="text" v-model="keywords" />
  </div>
</template>

<script>
import { watch, ref, reactive } from "@vue/composition-api";
export default {
  setup() {
    const keywords = ref("");
    // 异步任务:打印用户输入的关键词
    const asyncPrint = val => {
      return setTimeout(() => {
        console.log(val);
      }, 1000);
    };

    watch(
      keywords,
      (keywords, prevKeywords, onCleanup) => {
        // 执行异步任务,并得到关闭异步任务的 timerId
        const timerId = asyncPrint(keywords);
        // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务
        onCleanup(() => clearTimeout(timerId));
      },
      { lazy: true }
    );
    return {
      keywords
    };
  }
};
</script>

下一章:(九)Vue3.x生命周期
上一章:(七)计算属性 - computed

ps:人就是要为自己活,为别人想。

相关文章

网友评论

      本文标题:(八)观察者 - watch

      本文链接:https://www.haomeiwen.com/subject/hhuwpktx.html