Vue 3教程09 - watchers


Watcher的作用

监测数据(data)或计算属性(computed property)的值,当该值发生变化时,自动执行相应代码。

下面代码(Vue 2版本)会监测当加速时,如果速度超过70,会提醒:

JavaScript
export default {
  // ...
  data() {
    return {
      speed: 0
    }
  },
  // methods: () ,
  // computed: {},
  watch: {
    speed(newValue, oldvalue) {
      if(newValue > oldValue && newValue === 70) {
        alert('You have reached the speed limit!');
      }
    }
  }
}

Vue 3版本:

JavaScript
<template>
  Speed: {{ speed }}<br/>
  <button @click="speed+=10">Click me</button>
</template>

<script>
import { ref, watch } from 'vue'

export default {
  name: 'Demo',
  setup() {
    let speed = ref(0)

    watch(speed, (newValue, oldValue) => {
      console.log("Speed", newValue, oldValue);
    })

    return {
      speed
    }
  }
}

如果要监视多个ref定义的响应式数据:

JavsScript
watch([speed, message], (newValue, oldValue) => {
  // ...
})

监视reactive所定义的数据

JavaScript
let student = reactive({
  id: '9901',
  name: 'Paul',
  score: 90
})

watch(student, (newValue, oldValue) => {
  // 注意,在当前Vue3版本中似乎无法获取oldValue
  // 同时,强制开启了deep watch,也就是说这个设置项无效
})

如果只监视reactive对象的某个属性:

JavaScript

watch(()=> return student.score, (newValue, oldValue) => {
  // ...
})

如果监视reactive对象的多个属性:

JavaScript
watch([()=> return student.score, ()=> return student.name], (newValue, oldValue) => {
  // ...
})

如果要监视嵌套对象的某个属性,需要添加deep:true

JavaScript

let student = reactive({
  id: '9901',
  name: 'Paul',
  score: {
    math: 99,
    chinese: 90,
    physics; 80
  }
})
watch([()=> return student.score, ()=> return student.name], (newValue, oldValue) => {
  // ...
}, {deep:true})

Watcher vs Computed properties

严格讲,可以使用watcher来替代计算属性,但一般不会这么做。一般情况下,计算属性的代码更为简洁,而watcher的代码会相对复杂些。

计算属性应用场景:

  • 从现有属性计算出推导属性
  • 减少变量长度:有些时候,需要好几个步骤才能推导出UI想要的属性值,这时需要使用计算属性

使用Watcher的场景:

  • 监测某个属性值,当达到某个阈值时触发相应操作
  • 当属性值发生变化时,需要调用一个API
  • 当需要根据旧值和新值进行特定处理时

Immediate Watcher

在默认情况下,页面被加载时,属性被初始化,但这个初始化操作并不会触发watcher。如果想要这样做的话,可以对watcher稍作修改(Vue 2版本):

JavaScript
watch: {
  speed: {
    handler(newValue, oldvalue) {
      if(newValue > oldValue && newValue === 70) {
        alert('You have reached the speed limit!');
      }
    },
    immediate: true,
  }
}

Vue 3版本

JavaScript
watch(speed, (newValue, oldValue) => {
  console.log("Speed", newValue, oldValue);
}, {immediate: true})

以上这种方式在需要调用API时可能会经常用到。

Deep Watcher

在默认情况下,Vue不会监测对象属性值的变化。如果想要实现这样的功能,需要使用deep属性:

markup
studentInfo: {
  handler(newValue) {
    // making API calls
    console.log(newValue.id, newValue.name);
  },
  deep: true
}

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !