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功能,它需要接收一个带有函数“onCleanup”的回调函数,在这个回调函数中,所涉及到的变量,都会被智能监听,当这些变量数据发生变化时,watchEffect 的回调函数就会被执行,所传入的“onCleanup”函数执行时,可用于副作用(指的是该功能以外的其它操作,如在监听中反间理异步请求)的清理。

watchEffect 的返回值是该清理副作用的函数,通过调用返回值,使watchEffect 失效。

const stop = watchEffect(() => {})

// 当不再需要此侦听器时:
stop()

 

onCleanup 的作用,是为了考虑到一些操作还没完成时,但数据再一次发生变化而触发watchEffect 时,对前一次未完成的操作进行停止或清理。

举个例子:

当 watchEffect 中监听 person.name 值,当person.name值发生改变时,触发watchEffect 并把person.name的值异步请求服务器。

但是,当异步请求还没完成之际,person.name 值再次发生改变,watchEffect 再次被触发,这就有可能上一次请求还完成,又要发一次请求,针对这样的问题,我们应该先清理上一次未完成的请求操作,再去处理新的请求,则可以调用 onCleanup() 方法

 

flush 是指 watchEffect 函数触发的时机,有三种情况,默认是 pre

pre 指的是,当监听数据发生改变时,在页面渲染前,就调用watchEffect 函数

post 指的是,当监听数据发生改变时,在页面演染完成后,再调用watchEffect 函数

sync 指的是,watchEffect 监听多个数据时,应保持同步触发,效率较低不建议使用

 

代码如下:

// 引用 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
     */
     const stop = watchEffect((onCleanup)=>{
      const x1 = person.job.j1.salary;
      (对 person.job.j1.salary 进行一些操作)
      const x2 = person.name;
      (对 person.name 进行一些操作)

      onCleanup(()=>{
         如果有异步请求,则需要在这里清理请求
      })
    },{
      flush:'pre'|'post'|'sync'
    })


    return {
      person
    }
  }
}

 

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Vue3 – watch 组合式API
简介 watch 是 Vue 提供的一个比较有用的功能,它可以监视数据发生变化时的自定义操作。在Vue3 中提供的 watch 功能与 Vue2 基本一样的,但使用上有一些不同。   watch Vue2 中的 watch ……
<<上一篇
下一篇>>