Vue3 – watch 组合式API

简介

watch 是 Vue 提供的一个比较有用的功能,它可以监视数据发生变化时的自定义操作。在Vue3 中提供的 watch 功能与 Vue2 基本一样的,但使用上有一些不同。

 

watch

Vue2 中的 watch

Vue2 中的watch 使用的是对象配置项,如下代码:

export default {
  name: 'App',
  data() {
    return {
      sum: 0,
     sum2: 0
    }
  },
  watch: {
    // 使用简易的声明watch方式
    sum(newValue, oldValue) {
      console.log("sum数据发生变化", newValue, oldValue)
    },

    // 使用对象配置的声明watch方式
    sum2:{
      // 初始化后即开启一次监视
      immediate:true,
      // 针对多种嵌套的对象进行深度监视
      deep:true,
      handler(newValue, oldValue){
        console.log("sum数据发生变化", newValue, oldValue)
      }
    }
  }
}

 

Vue3 中的 watch

Vue3 中的 watch 需要引入才能使用,并且,Vue3的 watch 是一个API方法,因此可以多次调用,并且,watch可以同时监视多个变量的数据变化,如下参考代码:

// 引用 watch 监视属性的引用
import {watch} from "vue"

export default {
  name: 'App',

  setup() {

    let sum = ref(0);
    let sum2 = ref(0);

    /**
     * Vue3 中的定义 watch 用法
     * 参数一:要监视的变量
     * 参数二:变量发生改变时的触发的方法体(Vue2中的 handler())
     * 参数三:对于变量监视的额处配置属性(如immediate和 deep参数)
     */
    watch(sum, (newValue, oldValue) => {
      console.log("sum数据发生改变", newValue, oldValue)
    }, {
      immediate: true,
      deep: true
    })

    /**
     * Vue3 中可以定义无数个 watch 方法来监视每一个变量
     * 也可以使用一个 watch 方法来一次监视多个变量
     * 参数一:使用数组包装要监视的多个变量
     * 参数二:变量发生改变时的触发的方法体(Vue2中的 handler()),接收到的 value 也将是提供数组
     * 参数三:对于变量监视的额处配置属性(如immediate和 deep参数)
     */
    watch([sum, sum2], (newValue, oldValue, onCleanup) => {
      // 这里的 newValue 和 oldValue 都将是数组包装的数据
      console.log("sum或sum2数据发生改变", newValue, oldValue)
    }, {immediate: true, deep: true});

    return {
      sum, sum2
    }
  }
}

 

watch 监视 reactive 响应式数据

watch 监听普通 reactive 响应式数据

对于普通的 reactive 响应式数据时,将强制开启深度监视。

// 引用 watch 监视属性的引用
import {reactive, watch} from "vue"

export default {
  name: 'App',

  setup() {

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })

    /**
     * watch 普通监听 reactive 响应式数据
     * 情况一:当普通监听 reactive 响应式数据时,
     * 会强制开启 deep:true 深度监听,即使关闭了,也会监听深度对象成员
     */
    watch(person, (newValue, oldValue, onCleanup) => {
      console.log("person数据发生变化", newValue, oldValue);
    }, {deep:false}) // 这里即使 deep:false ,但依然产生深度监视

    return {
      person
    }
  }
}

 

watch 监听 reactive 响应式数据中的普通数据成员

当我只希望监听 reactive 响应式数据里的基础数据类型时的代码如下

// 引用 watch 监视属性的引用
import {reactive, watch} from "vue"

export default {
  name: 'App',

  setup() {

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    

    /**
     * watch 监听 reactive 响应式数据中的普通类型数据
     * 情况二:当监听 reactive 响应式数据中的普通类型数据时
     * 不可以直接使用监听,需要使用方法返回值的方式获得
     * 使用这种方式的监听,newValue, oldValue 是有效的
     */
    watch(() => person.name, (newValue, oldValue, onCleanup) => {
      console.log("person.name数据发生变化", newValue, oldValue)
    })

    return {
      person
    }
  }
}

 

watch 监听 reactive 响应式数据中的对象成员

如果 reactive 响应式数据里嵌套了对象数据时,若我只希望监听该对象数据时的代码如下:

// 引用 watch 监视属性的引用
import {reactive, watch} from "vue"

export default {
  name: 'App',

  setup() {

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })


    /**
     * watch 监听 reactive 响应式数据中的对象数据
     * 情况三:当监听 reactive 响应式数据中的对象数据时
     * deep 将会生效,不加上deep:true 时,将监听不到数据变化
     * 使用这种方式的监听,newValue, oldValue 是有效的
     */
    watch(() => person.job, (newValue, oldValue, onCleanup) => {
      console.log("person.job数据发生变化", newValue, oldValue)
    }, {deep: true})

    return {
      person
    }
  }
}

 

watch 监听 reactive 响应式数据中的多个普通数据

同样需要使用 ()=>xx 方式返回数据,否则会出现无法监听的问题。

// 引用 watch 监视属性的引用
import {reactive, watch} from "vue"

export default {
  name: 'App',

  setup() {

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })


    /**
     * watch 监听 reactive 响应式数据中的多个普通数据
     * 情况四:当监听 reactive 响应式数据中的多个普通数据时
     *
     * 使用这种方式的监听,newValue, oldValue 是有效的
     */
    watch([() => person.name, () => person.age], (newValue, oldValue, onCleanup) => {
      console.log("person中的普通数据发生变化", newValue, oldValue)
    })

    return {
      person
    }
  }
}

 

 

watchEffect

watchEffect 是Vue3 新推出的一种watch功能,它需要接收一个无参的回调函数,它不需要定义监听对象,回调函数中使用到了什么对象数据,它就会智能的监听什么对象,当回调函数中使用到的对象数据发生变化时,它就会发生监听触发。

代码如下:

// 引用 watchEffect 监视属性的引用
import {reactive, watchEffect} from "vue"

export default {
  name: 'App',

  setup() {

    let person = reactive({
      name: "张三",
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })

    /**
     * watchEffect 会对其回调函数中被使用的数据进行智能监听
     * 本例中,回调函数中使用了 person.job.j1.salary 和 person.name 数据
     * 则当这两个数据发生变化时,watchEffect会被触发
     * 而没有在回调函数中使用的数据(如 person.age)被改变时, 不会触发 watchEffect
     */
    watchEffect(()=>{
      const x1 = person.job.j1.salary;
      const x2 = person.name;
    })


    return {
      person
    }
  }
}

 




Leave a Reply

Your email address will not be published.


Comment


Name

Email

Url