Vue中的Computed与watch怎么用
这篇“Vue中的Computed与watch怎么用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue中的Computed与watch怎么用”文章吧。
computed
computed只接收一个getter函数
getter必须有返回值
computed返回一个只读响应式ref对象 (只读、响应式、对象)
注意:omputed只接收一个getter函数时,返回的只读对象,也就是不能修改他的返回值!
getter触发条件
computed返回值首次被读取时
getter绑定的响应式变量被修改时
<script setup>import { ref,computed } from 'vue'const num = ref(1)//computed返回一个只读响应式ref对象computedNum//computedNum是只读属性let computedNum = computed(() => num.value + 1)</script><template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <!-- 修改响应式变量num 触发与之绑定的computed的getter--> <button @click="num++">num++</button> <!-- computedNum是只读属性--> <button @click="computedNum++">computedNum++</button></template>
computed同时接收getter函数对象和setter函数对象
setter函数对象没有返回值
computed返回一个可读可写响应式对象
setter函数对象有参数,是getter的返回值,也是computed的值
修改computed返回值,触发setter函数对象执行,但不会真正修改computed返回值(setter内改变getter计算值就会改变computed返回值)
setter触发条件
computed返回值被修改时
实例:
<script setup>import { ref, computed } from 'vue'const num = ref(1)//getter(只读)let computedNum = computed(() => num.value + 1)//getter和setter (可读可写)let computedNum2 = computed({ get: () => num.value + 1, set: (val) => { console.log(val); //setter中修改ref响应式变量num,将触发关联的num的getter计算 //computedNum和computedNum2的getter同时触发 num.value++ }})</script><template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <p>computedNum2:{{ computedNum2 }}</p> <button @click="num++">num++</button> <!-- computedNum是只读属性,会有警告提醒 Write operation failed: computed value is readonly--> <button @click="computedNum++">computedNum++</button> <!-- computedNum2是可读可写属性--> <button @click="computedNum2++">computedNum2++</button></template>
调试 Computed
使用范围:仅开发模式生效
computed的第二参数:带有 onTrack
和 onTrigger
选项的对象
onTrack
:getter关联的响应式数据时触发。onTrigger
:getter关联的响应式数据被修改时触发
<script setup>import { ref, computed } from 'vue'const num = ref(1)let computedNum = computed(() => num.value + 1, { onTrack: (e) => { console.log('onTrack'); console.log(e); }, onTrigger: (e) => { console.log('onTrigger'); console.log(e); }})</script><template> <p> num:{{ num }} </p> <p>computedNum:{{ computedNum }}</p> <!--每次 num++将触发onTrigger --> <button @click="num++">num++</button></template>
watchEffect
语法:
参数1:触发监听回调函数,回调函数可传入一个onInvalidate函数作为参数!
可选参数2:对象,包含3个可选属性flush、onTrack、onTrigger
立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
会立即执行一次(和watch的immediate属性效果一致)
关联的响应式数据被修改时触发
会自动感知代码依赖,和watch不一样,watchEffect会主动绑定监听数据
局限性:不能监听对象(但可以监听对象的属性),只能监听类似ref基本数据类型的响应式数据
立即执行 监听基本数据类型
<script setup>import { ref, watchEffect } from 'vue'const num = ref(1)//会立即执行一次watchEffect(() => { console.log('watchEffect'); num.value++})</script><template> <p>num: {{ num }}</p> <button @click="num++">num++</button></template>
停止watchEffect
隐式:组件卸载时自动停止
显式:调用watchEffect
返回值
const stop = watchEffect(() => { })// 显式停止stop()
清理watchEffect
语法: watchEffect( onInvalidate=>{ onInvalidate(()=>{ }) })
onInvalidate 是一个函数!优先触发!
onInvalidate 执行时机:
watchEffect被重新触发时
组件卸载时
注意:关联的响应式数据首次被修改时不会触发onInvalidate函数!
作用: 清理定时器、事件监听removeEventListener 。。。
import { ref, watchEffect } from 'vue'const num = ref(1)watchEffect((onInvalidate ) => { console.log('watchEffect-1'); num.value++ onInvalidate (()=>{ console.log('onInvalidate-2'); }) console.log('watchEffect-3');})//1、watchEffect 被重新触发时// onInvalidate-2// watchEffect-1// watchEffect-3//2、组件卸载时// onInvalidate-2//3、关联的响应式数据首次被修改(组件被挂载时)// watchEffect-1// watchEffect-3
watchPostEffect 和 watchSyncEffect
watchPostEffect
和 watchSyncEffect
在Vue3.2新增,是watchEffect类似语法糖的东西,
是watchEffect
可选参数对象{ flush?: 'pre' | 'post' | 'sync'}
中post和sync的语法糖,pre是默认值
推迟触发watchPostEffect
watchPostEffect
是watchEffect可选参数对象{flush:'post'}
的语法糖
推迟watchEffect触发时机!组件更新前触发!也就是在生命周期onBeforeUpdate
和 onUpdated
之间触发
语法:
//推迟触发watchEffectwatchEffect( () => { }, { flush: 'post' })//Vue3.2语法糖watchPostEffectwatchPostEffect(()=>{ })
实例:
//实验watchEffect第二参数 flush: 'post'属性watchEffect(() => { console.log("实验watchEffect第二参数 {flush: 'post'}属性"); console.log(obj.age);},{ flush:'post' })watchEffect(() => { console.log("watchEffect正常时机触发"); console.log(obj.age);})//生命周期onUpdatedonUpdated(()=>{ console.log('onUpdated()'); })//生命周期onBeforeUpdateonBeforeUpdate(()=>{ console.log('onBeforeUpdate()');})
修改obj.age
时,执行结果:
watchEffect正常时机触发
onBeforeUpdate()
实验watchEffect第二参数 {flush: 'post'}属性
onUpdated()
同步触发watchSyncEffect
watchSyncEffect
是watchEffect可选参数对象{flush:'sync'}
的语法糖
强制效果始终同步触发!效率低!也就是默认watchEffect之前触发
语法:
watchEffect( () => { }, { flush: 'sync' })//Vue3.2语法糖watchSyncEffectwatchSyncEffect(()=>{ })
watchEffect不能监听对象
//假设修改了对象的属性值-修改了obj.ageconst obj = reactive({ name: '小明', age: 18 })//watchEffect不能监听对象变化watchEffect(() => { console.log('watchEffect监听对象变化'); console.log(obj);})//watchEffect可以监听对象属性变化watchEffect(() => { console.log('watchEffect监听对象属性变化'); console.log(obj.age);})//watch监听对象变化watch(obj, (obj) => { console.log('watch监听对象变化'); console.log(obj);})
总结:watchEffect
用来监听能监听基本数据类型,不能监听对象,但能监听对象的属性;watch能监听基本数据类型和对象!
watch
语法:
参数1-被监听数据(形式:单个数据、数组、带返回值的回调函数)
参数2-触发监听的回调函数,无返回值
可选参数3-对象
{immediate: true,deep:true}
,对象含2个可选参数和Vue2参数效果一致
Vue3的watch和Vue2的watch是基本一样的
需要指定监听数据
惰性,只在被监听数据变化时才触发(immediate属性可以设置在初始化的时候触发)
监听单个数据
参数1被监听数据的形式:
单个基本数据类型;
回调函数:返回值为单个基本数据类型;
// 侦听一个 getter//被监听数据传入一个带返回值的回调函数const state = reactive({ count: 0 })watch( () => state.count, (count, prevCount) => { })// 直接侦听一个 refconst count = ref(0)watch(count, (count, prevCount) => { })
监听多个数据(传入数组)
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => { })
官方文档总结
以下代码截取官方文档,从TS代码可以看出很多关于watch和watchEffect函数参数和返回值的细节!
computed
computed
只接收一个getter函数
getter
触发条件:
computed返回值首次被读取时
getter绑定的响应式变量被修改时
computed
同时接收getter函数对象和setter函数对象
setter
触发条件:computed返回值被修改时
// 只读的function computed<T>( getter: () => T, debuggerOptions?: DebuggerOptions): Readonly<Ref<Readonly<T>>>// 可写的function computed<T>( options: { get: () => T set: (value: T) => void }, debuggerOptions?: DebuggerOptions): Ref<T>interface DebuggerOptions { onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void}interface DebuggerEvent { effect: ReactiveEffect target: any type: OperationTypes key: string | symbol | undefined}
watchEffect
参数1-触发监听回调函数,回调函数可传入一个onInvalidate函数作为参数!
可选参数2-对象,包含3个可选属性flush、onTrack、onTrigger
function watchEffect( effect: (onInvalidate: InvalidateCbRegistrator) => void, options?: WatchEffectOptions): StopHandleinterface WatchEffectOptions { flush?: 'pre' | 'post' | 'sync' // 默认:'pre' onTrack?: (event: DebuggerEvent) => void onTrigger?: (event: DebuggerEvent) => void}interface DebuggerEvent { effect: ReactiveEffect target: any type: OperationTypes key: string | symbol | undefined}type InvalidateCbRegistrator = (invalidate: () => void) => voidtype StopHandle = () => void
watch
参数1-被监听数据(形式:单个数据、数组、带返回值的回调函数)
参数2-触发监听的回调函数,无返回值
参数3-传入
{immediate: true,deep:true}
对象和Vue2参数效果一致
// 侦听单一源function watch<T>( source: WatcherSource<T>, callback: ( value: T, oldValue: T, onInvalidate: InvalidateCbRegistrator ) => void, options?: WatchOptions): StopHandle// 侦听多个源function watch<T extends WatcherSource<unknown>[]>( sources: T callback: ( values: MapSources<T>, oldValues: MapSources<T>, onInvalidate: InvalidateCbRegistrator ) => void, options? : WatchOptions): StopHandletype WatcherSource<T> = Ref<T> | (() => T)type MapSources<T> = { [K in keyof T]: T[K] extends WatcherSource<infer V> ? V : never}// 参见 `watchEffect` 共享选项的类型声明interface WatchOptions extends WatchEffectOptions { immediate?: boolean // 默认:false deep?: boolean}
以上就是关于“Vue中的Computed与watch怎么用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341