• Vue 3 中,watch 和 watchEffect 的区别


    结论先行: 

    watch 和 watchEffect 都是监听器,都是用来监听响应式数据的变化并执行相应操作。区别是: 

    watch:需要指明要监听的数据,而且在回调函数中可以获取到属性变化的前后值;

    适用于需要精确控制监视范围的情况;也就是需要针对特定数据变化执行操作。

    watchEffect:不用指明监听哪个属性,回调中用到哪个响应式数据,那就监听哪个。

    适用于不需要明确定义监视的数据,只需在回调函数内部使用响应式数据并执行相应操作的场景。也就是只需根据数据变化自动追踪的操作。

    watchEffect 有点像计算属性 computed:但计算属性必须要写返回值,而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。

    而且,computed 若是值没有被使用时不会调用,但是 watchEffect 始终会调用一次。

    具体解析: 

    watch 和 watchEffect 都是监听器(侦听器)。用来监听响应式数据的变化并执行相应操作

    1、watch  

    • 用于对特定的响应式数据进行监视,并在数据变化时执行相应的操作。
    • 需要显式地指定要监视的数据,并提供回调函数来响应数据变化。
    • 除了监视简单的数据变化外,还可以处理更复杂的监视需求,如监听嵌套对象或数组的变化,并执行相应的操作。
    • 具有一定的惰性。第一次页面展示的时候不会执行,只有数据变化的时候才会执行(设置immediate: true 时可以变为非惰性,页面首次加载就会执行)

    它接受3个参数:

    • 一个响应式引用 ref 或一个返回值的 getter 函数
    • 一个回调
    • 可选的配置选项
    ① watch 侦听单个数据源 
    1. import { ref, watch } from 'vue'
    2. const counter = ref(0)
    3. watch(counter, (newValue, oldValue) => {
    4. console.log('The new counter value is: ' + counter.value)
    5. })

    应用到实际例子中:

    1. // src/components/UserRepositories.vue `setup` function
    2. import { fetchUserRepositories } from '@/api/repositories'
    3. import { ref, onMounted, watch, toRefs } from 'vue'
    4. export default {
    5. components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
    6. props: {
    7. user: {
    8. type: String,
    9. required: true
    10. }
    11. },
    12. // 在我们组件中
    13. setup (props) {
    14. // 使用 `toRefs` 创建对prop的 `user` property 的响应式引用
    15. const { user } = toRefs(props)
    16. const repositories = ref([])
    17. const getUserRepositories = async () => {
    18. // 更新 `prop.user` 到 `user.value` 访问引用值
    19. repositories.value = await fetchUserRepositories(user.value)
    20. }
    21. onMounted(getUserRepositories)
    22. // 在用户 prop 的响应式引用上设置一个侦听器
    23. watch(user, getUserRepositories)
    24. return {
    25. repositories,
    26. getUserRepositories
    27. }
    28. }
    29. },

    在我们的 setup 的顶部使用了 toRefs。这是为了确保我们的侦听器能够对 user prop 所做的更改做出反应

    ② watch 侦听多个数据源

    第一个参数以数组形式传入,第二个参数回调返回的结果也是数组

    1. watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
    2. /* ... */
    3. })

    Vue3 中监听 reactive 中的值,必须以 getter 函数 的形式,不然会报错。和 Vue2 的区别是不用写 deep 属性,默认就是深度监听了。 

    1. watch([result2, () => data.title], (newV, oldV) => {
    2. console.log(newV, oldV) //  [20, "111"] [20, "222"]
    3. })

     监听 reactive 中的多个值时: 

    1. watch([result2, () => [data.title, data.value1]], (newV, oldV) => {
    2. console.log(newV, oldV)
    3. })

    2、watchEffect

    立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。

    • 用于创建一个自动追踪其依赖,并在依赖变化时自动运行的响应式副作用
    • 不需要显式地指定要监视的数据,而是根据回调函数内部使用到的响应式数据自动建立依赖关系。
    • 适用于无需明确定义监视的数据,只需在回调函数内部使用响应式数据并执行相应操作的场景。
    • 立即执行,没有惰性,页面的首次加载就会执行

    • 无法获取到原值,只能得到变化后的值

    1. <template>
    2. <div>
    3. <h1>watchEffect - 侦听器h1>
    4. <p>{{data.count}}p>
    5. <button @click="stop">手动关闭侦听器button>
    6. div>
    7. template>
    8. <script>
    9. import { reactive, watchEffect } from "vue";
    10. export default {
    11. name: "WatchEffect",
    12. setup() {
    13. const data = reactive({ count: 1 });
    14. const stop = watchEffect(() => console.log(`侦听器:${data.count}`));
    15. setInterval(() => {
    16. data.count++;
    17. }, 1000);
    18. return { data, stop };
    19. }
    20. };
    21. script>

     结果:

    3、总结  

    watch:既要指明要监听的属性,也要指明回调。

    watchEffect:不用指明监听哪个属性,回调中用到哪个属性,那就监听哪个属性。

    watchEffect 有点像计算属性 computed:

    但 computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

    而 watchEffect 更注重的是过程(回调函数的函数体),所以不用写返回值。

    与 watchEffect 比较,watch 允许我们:

    • 懒执行副作用;
    • 更具体地说明什么状态应该触发侦听器重新运行;
    • 访问侦听状态变化前后的值。
  • 相关阅读:
    光伏、储能双层优化配置接入配电网研究(附带Matlab代码)
    idea快速搭建struts2框架
    国庆七天乐,写博也快乐之微信小程序天气预报+根据天气自动变换背景图实战(使用和风天气API)
    Element 自定义指令 下拉分页,获取无限数据
    图形学-着色频率与渲染管线
    [算法刷题笔记]二叉树练习(3)完全二叉树的节点个数
    conda config包含无效channel解决办法
    我的创作纪念日
    4 Spring ApplicationListener 问题版
    TypeScript基础之object、Object、{}区别
  • 原文地址:https://blog.csdn.net/qq_38290251/article/details/134271782