欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > vue3学习记录-watch

vue3学习记录-watch

2025/2/24 19:49:41 来源:https://blog.csdn.net/qq_45030898/article/details/142598412  浏览:    关键词:vue3学习记录-watch

vue3学习记录-watch

  • 1.watch
  • 2.watchEffect
    • 2.1 watchEffect使用
    • 2.2 watchEffect好处
      • 2.2.1 消除手动维护依赖列表的负担
      • 2.2.2 侦听一个嵌套数据结构中的几个属性

1.watch

直接总结下。。。

<script setup>
import { ref, reactive, computed, watch } from 'vue'const input = ref('小邱')
const input1 = ref('小小邱')
const input3 = ref('3')
const input4 = ref('4')
const x = ref('1')
const y = ref('2')
const obj = reactive({a: {b: {c: 1}}
})
const obj2 = reactive({a: {b: {c: 1}}
})
const obj3 = reactive({a: {b: {c: 1}}
})
//单个监听
watch(input, (newval, oldval) => {console.log(newval, oldval)
})
watch(input1, (newval, oldval) => {console.log(newval, oldval)
})//深度监听
//深度监听对象 监听前后的值都是新值
watch(obj3, (newval, oldval) => {console.log('深层监听', newval, oldval)
})
//不能直接侦听响应式对象的属性值 !
watch(obj.a.b.c, (newval, oldval) => {console.log('深层监听obj.a.b.c', newval, oldval)
})
watch(() => obj.a.b.c, (newval, oldval) => {console.log('深层监听obj.a.b.c', newval, oldval)
})//一次监听多个
watch([input3, input4], (newval, oldval) => {console.log(newval, oldval)
})
watch([input3, () => input4.value], (newval, oldval) => {console.log('多个input监听箭头函数写法', newval, oldval)
})
watch([input3,() => obj2.a.b.c], (newval, oldval) => {console.log('多个input监听带深层属性', newval, oldval)
})
//多个input监听带深层对象 监听前后的值都是新值
watch([input3,obj2], (newval, oldval) => {console.log('多个input监听带深层对象', newval, oldval)
})// getter 函数
watch(() => x.value + y.value,(sum, oldsum) => {console.log(`sum of x + y is: ${sum},oldsum:${oldsum}`)}
)
//这样写算是错误写法 监听不到 因为x+y不是一个响应式对象
watch(() => x + y,(sum, oldsum) => {console.log(`sum111 of x + y is: ${sum},oldsum:${oldsum}`)}
)
</script><template><div class="app"><div class="content"><p>单个监听</p><el-input v-model="input"></el-input><el-input v-model="input1"></el-input><p>深度监听</p><el-input v-model="obj3.a.b.c"></el-input><el-input v-model="obj.a.b.c"></el-input><p>一次监听多个</p><el-input v-model="input3"></el-input><el-input v-model="input4"></el-input><el-input v-model="obj2.a.b.c"></el-input><p>getter 函数</p><el-input-number v-model="x"></el-input-number><el-input-number v-model="y"></el-input-number></div></div></template><style scoped>
.app {display: flex;align-items: center;justify-content: center;
}
</style>

2.watchEffect

2.1 watchEffect使用

侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 todoId 的引用发生变化时使用侦听器来加载一个远程资源:

const todoId = ref(1)
const data = ref(null)watch(todoId,async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()},{ immediate: true }
)

特别是注意侦听器是如何两次使用 todoId 的,一次是作为源,另一次是在回调中。其实,这样写也是可以的。

watch(todoId,async (newVal) => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${newVal}`)data.value = await response.json()},{ immediate: true }
)

我们可以用 watchEffect 函数 来简化上面的代码。watchEffect() 允许我们自动跟踪回调的响应式依赖。上面的侦听器可以重写为:

watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})

2.2 watchEffect好处

2.2.1 消除手动维护依赖列表的负担

对于这种只有一个依赖项的例子来说,watchEffect() 的好处相对较小。但是对于有多个依赖项的侦听器来说,使用 watchEffect() 可以消除手动维护依赖列表的负担。

import { ref, watchEffect } from 'vue';setup() {const x = ref(1);const y = ref(2);const z = ref(3);watchEffect(() => {console.log(`x + y + z = ${x.value + y.value + z.value}`);});// 后续对 x, y, z 的任何修改都会触发 watchEffect 中的函数
}

在这个例子中,我们创建了三个响应式引用 x、y 和 z。然后我们使用 watchEffect 来观察它们的和。由于我们没有指定依赖项,watchEffect 会自动追踪 x.value、y.value 和 z.value。无论 x、y 还是 z 发生变化,watchEffect 中的函数都会被重新执行,并打印出新的和。

如果你使用 watch 来实现同样的功能,你需要手动指定依赖项:

import { ref, watch } from 'vue';setup() {const x = ref(1);const y = ref(2);const z = ref(3);watch(() => x.value + y.value + z.value,(newSum) => {console.log(`x + y + z = ${newSum}`);});// 这需要你手动维护依赖项列表,当依赖项增加时,你需要更新 watch 的第一个参数
}

使用 watchEffect 可以简化这个过程,因为你不需要手动维护依赖项列表。当项目中的状态变化比较复杂或者依赖项很多时,watchEffect 可以大大简化代码。举个例子,假设你正在开发一个购物车应用,用户可以选择多种商品并修改它们的数量。你需要根据选中的商品和它们的数量计算总价。这个总价依赖于多个商品的选中状态和数量,这是一个典型的多依赖项场景。
以下是不使用 watchEffect 时可能的代码:

import { ref, watch } from 'vue';const product1Selected = ref(false);
const product1Quantity = ref(0);
const product2Selected = ref(false);
const product2Quantity = ref(0);
// ...可能还有更多商品let totalPrice = ref(0);watch([product1Selected, product1Quantity, product2Selected, product2Quantity], ([newSel1, newQty1, newSel2, newQty2], [oldSel1, oldQty1, oldSel2, oldQty2]) => {totalPrice.value = 0;if (newSel1) totalPrice.value += product1Price * newQty1;if (newSel2) totalPrice.value += product2Price * newQty2;// ...对更多商品进行处理
}, { immediate: true });

现在,如果使用 watchEffect,你可以简化这个过程:

import { ref, watchEffect } from 'vue';const product1Selected = ref(false);
const product1Quantity = ref(0);
const product2Selected = ref(false);
const product2Quantity = ref(0);
// ...可能还有更多商品const product1Price = 100;
const product2Price = 200;
// ...更多商品价格watchEffect(() => {let totalPrice = 0;if (product1Selected.value) totalPrice += product1Price * product1Quantity.value;if (product2Selected.value) totalPrice += product2Price * product2Quantity.value;// ...对更多商品进行处理console.log(`Total Price: ${totalPrice}`);
});

2.2.2 侦听一个嵌套数据结构中的几个属性

此外,如果你需要侦听一个嵌套数据结构中的几个属性,watchEffect() 可能会比深度侦听器更有效,因为它将只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性。
假设你有一个用户对象,其中包含用户的个人信息和订单信息,但你可能只关心用户的名字和最后下单的时间:

import { ref, reactive, watchEffect } from 'vue';const user = reactive({name: 'John Doe',age: 30,address: {street: '123 Main St',city: 'Anytown',zip: '12345'},orders: [{id: 1,product: 'Widget',timestamp: new Date('2021-06-01')},{id: 2,product: 'Gadget',timestamp: new Date('2021-06-02')}]
});watchEffect(() => {// 只响应 name 和 orders 数组中最后一个订单的 timestampconsole.log(`User Name: ${user.name}`);console.log(`Last Order Time: ${user.orders[user.orders.length - 1].timestamp}`);
});

在这个例子中,watchEffect 会追踪 user.name 和 user.orders 数组(具体是数组中最后一个元素的 timestamp 属性)。当 user.name 发生变化,或者 user.orders 数组中添加了新订单(导致数组长度变化)或者最后一个订单的 timestamp 发生变化时,watchEffect 的回调函数会被触发。

相比之下,如果你使用 watch 来深度监听整个 user 对象,就像这样:

import { watch } from 'vue';watch(() => user,(newValue, oldValue) => {// 这个回调会在 user 对象的任何属性变化时执行console.log('User data changed');},{ deep: true }
);

这会导致每当 user 对象的任何属性发生变化时,包括用户的地址或订单详情等,回调函数都会被触发,这可能会导致不必要的性能开销。

使用 watchEffect 的好处是它只会响应你实际关心的数据变化,而不是整个对象树的每个属性变化,这样可以提高应用的性能和响应速度。
学习ing,后续随缘再更新

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词