何为watch:
文档定义:
用于声明在数据更改时调用的侦听回调。
watch
选项期望接受一个对象,其中键是需要侦听的响应式组件实例属性 (例如,通过 data
或 computed
声明的属性)——值是相应的回调函数。该回调函数接受被侦听源的新值和旧值。
除了一个根级属性,键名也可以是一个简单的由点分隔的路径,例如 a.b.c
。注意,这种用法不支持复杂表达式——仅支持由点分隔的路径。如果你需要侦听复杂的数据源,可以使用命令式的 $watch() API。
值也可以是一个方法名称的字符串 (通过 methods
声明),或包含额外选项的对象。当使用对象语法时,回调函数应被声明在 handler
中。额外的选项包含:
immediate
:在侦听器创建时立即触发回调。第一次调用时,旧值将为undefined
。deep
:如果源是对象或数组,则强制深度遍历源,以便在深度变更时触发回调。详见深层侦听器。flush
:调整回调的刷新时机。详见回调的触发时机及 watchEffect()。onTrack / onTrigger
:调试侦听器的依赖关系。详见侦听器调试。
声明侦听器回调时避免使用箭头函数,因为它们将无法通过 this
访问组件实例。
概述:
作用:监视数据的变化(和
Vue2
中的watch
作用一致)特点:
Vue3
中的watch
只能监视以下四种数据:
ref
定义的数据。
reactive
定义的数据。函数返回一个值(
getter
函数)。一个包含上述内容的数组。
情况1:
监视ref
定义的【基本类型】数据:直接写数据名即可,监视的是其value
值的改变。
情况一:监视【ref】定义的【基本类型】数据
当前求和为:{{sum}}
情况2:
监视ref
定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
注意:
若修改的是
ref
定义的对象中的属性,newValue
和oldValue
都是新值,因为它们是同一个对象。若修改整个
ref
定义的对象,newValue
是新值,oldValue
是旧值,因为不是同一个对象了。
情况二:监视【ref】定义的【对象类型】数据
姓名:{{ person.name }}
年龄:{{ person.age }}
情况3:
监视reactive
定义的【对象类型】数据,且默认开启了深度监视。
情况三:监视【reactive】定义的【对象类型】数据
姓名:{{ person.name }}
年龄:{{ person.age }}
测试:{{obj.a.b.c}}
情况4:
监视ref
或reactive
定义的【对象类型】数据中的某个属性,注意点如下:
若该属性值不是【对象类型】,需要写成函数形式。
若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。
结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。
情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性
姓名:{{ person.name }}
年龄:{{ person.age }}
汽车:{{ person.car.c1 }}、{{ person.car.c2 }}
情况5:
监视上述的多个数据
情况五:监视上述的多个数据
姓名:{{ person.name }}
年龄:{{ person.age }}
汽车:{{ person.car.c1 }}、{{ person.car.c2 }}
注意:
监听过程中由于浅拷贝和深拷贝的原因可能会出现newvalue和oldvalue相同的情况。
通过深拷贝(以扩展运算符为例),解决newValue与 oldValue值相同问题
const refData = ref(['a','b','c'])
watch(
() => [...refData.value],
(newValue, oldValue) => {
console.log(newValue, oldValue)
},
{ deep: true }
)
watchEffect:
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。
watch
对比watchEffect
都能监听响应式数据的变化,不同的是监听数据变化的方式不同
watch
:要明确指出监视的数据watchEffect
:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。
需求:水温达到50℃,或水位达到20cm,则联系服务器
水温:{{temp}}
水位:{{height}}
有点组件的全局引入和精确引入的感觉。