Vue watch() 与 watchEffect()简介
watch()
函数原型:
@原型:watch( param, callback, options) @params: param: [必需] 被监听对象 callback: [必需] 被监听对象发生变化时执行回调 callback: function(newValue, oldValue) { // newValue 变化后的值 // oldValue 变化前的值 } options: [可选] 监听参数 options: { deep: true, //[true| false] 值true表示深度监听 immediate: false, //[true|false] 默认wath是懒执行,设置值为true表示初始化时就执行一次,使其具有和watchEffect() 一样的特性 flush: 'pre' // ['pre|post|sync] 控制回调时间 // pre: 默认值。回调应该在渲染前被调用 // post: 将回调推迟到渲染之后的 // sync: 一旦值发生了变化,回调将被同步调用 }
@return: [Fun] 执行该函数用于中止监听
监听ref对象
<script setup> import { ref, watch } from 'vue' const studentNumber = ref(0) watch( studentNumber, (newV, oldV) => { console.log(newV); }, { immediate: true //使监听初始化时就执行一次 }) </script>
监听函数、表达式
<script setup> import { ref, watch } from 'vue' const studentNumber = ref(10) watch( // 注意:第一个参数是一个函数。它监听函数的返回值 () => studentNumber.value * 5, (newV, oldV) => { // 这里的newV值是函数返回值的结果 console.log('总班费:' + newV + '元'); }) </script>
监听reactive对象
<script setup> import { reactive, watch } from 'vue' const student = reactive({ name: '张三', age: 15, contact: { phone: '18714896998', qq: '103422412', email: 'wm218@qq.com' } }) watch(student, (newV, oldV) => { console.log(newV); }) </script>
监听reactive对象的某个属性
不能直接监听student.name,因为它返回是的一个值,而不是对象。所以这里采用监听函数的方式来实现
<script setup> import { reactive, watch } from 'vue' const student = reactive({ name: '张三', age: 15, contact: { phone: '18714896998', qq: '103422412', email: 'wm218@qq.com' } }) watch(
() => student.name,
(newV, oldV) => { console.log(newV); }) </script>
监听计算属性
<script setup> import { ref, watch, computed } from 'vue' const studentNumber = ref(0) // 定义计算属性 const getMoney = computed(() => studentNumber.value * 5) watch(getMoney, (newV, oldV) => { console.log('总班费:' + newV + '元'); }) </script>
监听多个数据
<script setup> import { ref, reactive, watch } from 'vue' const studentNumber = ref(0) const student = reactive({ name: '张三', age: 15, contact: { phone: '18714896998', qq: '103422412', email: 'wm218@qq.com' } }) watch( //将多个数据以数组元素代入 [studentNumber, () => student.name], // 注意这里是将新值放在一个数组,旧值放在第二个数组 // [新值1,新值2], [旧值1,旧值2] ([studentNumberNewV, nameNewV], [studentNumberOldV, nameOldV]) => { console.log(studentNumberNewV); console.log(studentNumberOldV); console.log(nameNewV + '===' + nameOldV); }) </script>
停止监听
<script setup> import { ref, watch } from 'vue' const studentNumber = ref(0) var stopWatch = watch( studentNumber, (newV, oldV) => { console.log(newV); }) // 执行 stopWatch() 可以停止监听 </script>
watchEffect()
watchEffect()特性:
1、watchEffect()会监听函数内所有出现的对象,无需特别指定对象。
//本例中函数使用了studentNumber,则其自动被认为是侦听对象,当其值发生变化时,自动触发 watchEffect(()=>{ console.log(studentNumber.value) })
2、不论watchEffect()内是否设置了侦听对象,初始化时它都会执行一次,比如以下代码:
// 虽然内部出现侦听对象,但也会执行 watchEffect(()=>{ console.log(222); // 初始化时这里会执行 })
3、watchEffect()不能侦听异步函数内对象。
// 由于studentNumber存在异步函数内,所以它不会被侦听 watchEffect( async ()=>{ await setTimeout(()=>{ console.log(studentNumber.value); }, 1000)
console.log(a.value); // 这里a也无法监听,官方的解释:只有在第一个 await 正常工作前访问到的属性才会被追踪。
// 我的理解是:只要前面的侦听失败,后面全部失败
})
函数原型:
@原型:watchEffect (callback, options) @params: callback: [必需] 回调函数 options: [可选] 监听参数 options: { flush: 'pre', // ['pre|post|sync] 控制回调时间 // pre: 默认值。回调应该在渲染前被调用 // post: 将回调推迟到渲染之后的 // sync: 一旦值发生了变化,回调将被同步调用 onTrack(e) { debugger }, onTrigger(e) { debugger } } @return: [Fun] 执行该函数用于中止监听
停止监听
const stopWatch = watchEffect(()=>{ console.log(studentNumber.value) }) //执行 stopWatch() 可执行监听
总结:watch() 与watchEffect()的区别
1、watch() 可以获取值的前后变化。而watchEffect()不可以。
2、watch() 默认属于懒执行.创建侦听时,不执行。而watchEffect()创建侦听时即执行一次。
3、watchEffect()写法自由些,但同时针对异步有点复杂情况。而watch() 执行条件明确。