管理数据必备;侦听器watch用法详解,vue2与vue3中watch的变化与差异

简介: 一篇文章同时搞定Vue2和Vue3的侦听器,是不是很棒?不要忘了Vue3中多了一个可选项watchEffect噢。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~


一、侦听器(watch)是什么?

       侦听器是一个在 Vue.js 框架中用于观察和响应数据变化的机制。侦听器允许开发者指定一个函数,这个函数会在特定数据变化时自动执行。Vue.js 使用侦听器来实现数据双向绑定和响应式更新。

       说简单点,侦听器常用来监听数据的变化,并在数据变化时捕获数据变化前后的值,并执行我们声明的回调函数。

image.gif 编辑

       就像现实中的监听设备一样,发现情况有变立马行动,只不过Vue中的侦听器只针对数据。

二、Vue2中的watch(Options API)

       在Vue2中,watch 是一个选项,你可以在组件中定义它来观察数据的变化。常用的包括函数式写法和对象式写法,以我个人的习惯,如果监听的需求比较简单, 也不会涉及到日后的拓展问题,就可以直接使用函数式,这样写起来简便;如果监听比较复杂,比如监听有多层的对象,或者需要用到immediate属性,又或者要方便日后拓展和维护,就用对象式,这样更清晰,更方便拓展。还有就是大型项目建议还是用对象式,统一用法比较好。

image.gif 编辑

2.1、函数式写法

       此时每个被侦听的属性被当做一个“函数”,这个函数就是被侦听的属性变化后所执行的回调函数,该函数接受两个参数,第一个是变化后的新值,第二个是变化前的旧值。

export default {
  data() {
    return {
      watchedProperty: ''
    };
  },
  watch: {
    // 当 watchedProperty 发生变化时,这个函数将被调用
    watchedProperty(newVal, oldVal) {
      // 在这里执行当 watchedProperty 改变时要执行的代码
      console.log(`从 ${oldVal} 变为 ${newVal}`);
    }
  }
};

image.gif

2.2、对象式写法

       ①对象式基础写法

       此时每个被侦听的属性被当做一个“对象”,这个对象名就是被侦听的属性名,该对象中有一个函数和若干个属性。基础写法如下:

export default {
  data() {
    return {
      dataProperty: ''
    };
  },
  watch: {
    // 观察 dataProperty 的变化
    dataProperty: {
      // 当 dataProperty 发生变化时,这个函数将被调用
      handler(newVal, oldVal) {
        console.log(`数据从 ${oldVal} 变更为 ${newVal}`);
      },
      // 深度观察
      deep: true,
      // 立即执行观察者函数
      immediate: true
    }
  }
};

image.gif

       ②回调函数handler

       对象式写法中有个函数名为handler,名称不可自定义,该函数为被监听属性变化后所执行的回调函数,该函数接受两个参数,第一个是变化后的新值,第二个是变化前的旧值。

       ③deep属性

       deep是常用的属性:缺省值为false,只监听表层变化,设置为true后可监听深层的数值,deep选项允许你观察对象内部属性的变化。如果没有设置deep,当对象内部的属性变化时,handler函数不会被触发。见下方例子:

export default {
  data() {
    return {
      userInfo: {
        name: 'John Doe',
        age: 30
      }
    };
  },
  watch: {
    userInfo: {
      handler(newVal, oldVal) {
        console.log(`用户信息从 ${JSON.stringify(oldVal)} 变更为 ${JSON.stringify(newVal)}`);
      },
      deep: true
    }
  }
};

image.gif

       在这个例子中,如果userInfo对象的name或age属性发生变化,handler函数将被调用,因为它使用了deep选项,但如果没有设置deep,那么只有在userInfo引用的内容发生变化时才会调用handler函数,比如将另外一个对象直接浅拷贝给userInfo。

       ④immediate属性

       immediate选项允许你在开始观察时立即执行handler函数。这一般是用在需要组件初始化时就立即执行handler函数的情况下。下面是一个例子:

export default {
  data() {
    return {
      initialData: 'Initial Value'
    };
  },
  watch: {
    initialData: {
      handler(newVal, oldVal) {
        console.log(`初始数据从 ${oldVal} 变更为 ${newVal}`);
      },
      immediate: true
    }
  },
  created() {
    // 组件创建时,我们改变initialData的值
    this.initialData = 'Changed Value';
  }
};

image.gif

三、Vue3中的watch

3.1、向下兼容(Vue2)的Options API

       在Vue3中,使用Options API时,watch的用法与Vue2相同。

export default {
  data() {
    return {
      watchedProperty: ''
    };
  },
  watch: {
    watchedProperty(newVal, oldVal) {
      console.log(`从 ${oldVal} 变为 ${newVal}`);
    }
  }
};

image.gif

3.2、使用Composition API

3.2.1、基础语法

       在Vue3的Composition API中,watch 以函数的形式存在,可以更细粒度地控制侦听器。watch函数接收两个参数:

  1. 被监听的属性:你想要观察的响应式数据源,可以是响应式引用 ref、计算属性 computed,或者返回响应式值的函数。
  2. 回调函数:当被监听的属性发生变化时调用的函数,它接收新值和旧值作为参数。

使用Composition API的watch提供了更大的灵活性,例如,你可以观察更复杂的响应式状态,或者使用watchEffect来自动追踪依赖并执行副作用。

3.2.2、基础用法示例

       在Vue 3的Composition API中,基础用法示例如下:

import { watch, ref } from 'vue';
export default {
  setup() {
    const watchedProperty = ref('');
    // 使用 watch 函数观察 watchedProperty 的变化
    watch(watchedProperty, (newVal, oldVal) => {
      console.log(`从 ${oldVal} 变为 ${newVal}`);
    });
    // 也可以观察其他响应式引用或计算属性
    // watch(() => someComputedProperty, (newVal, oldVal) => { ... });
    // 返回响应式状态供模板或其他Composition API使用
    return {
      watchedProperty
    };
  }
};

image.gif

3.2.3、Vue3中的对象式写法

       写法核心思想和Vue2差不多,只不过变成了箭头函数,随便给个例子就能看懂:

import { ref, watch } from 'vue';
// 创建响应式引用
const state = ref({
  name: 'John Doe',
  age: 30
});
// 使用 watch 函数,同时设置 deep 和 immediate 选项
watch(
  () => state.value, // 观察的响应式源
  (newVal, oldVal) => {
    console.log(`State changed from ${JSON.stringify(oldVal)} to ${JSON.stringify(newVal)}`);
  },
  {
    deep: true,    // 深度观察,观察对象内部属性的变化
    immediate: true // 立即执行观察者函数
  }
);

image.gif

四、Vue3中的watchEffect

       Vue3提倡使用 watchEffect 自动追踪依赖并执行副作用,而不是直接用watch来进行简单的副作用的侦听。副作用通常是指那些与组件渲染无关的操作,如 API 调用、手动更改 DOM 等。watchEffect 不需要显式指定要观察的响应式状态,它会自动追踪其内部使用的响应式引用和状态。这减少了样板代码,当开发者只是想要观察属性的变化时,不用写那么多重复的代码。

import { ref, watch, watchEffect } from 'vue';
export default {
  setup() {
    // 创建响应式状态
    const count = ref(0);
    // 使用 watchEffect 自动追踪 count 并执行副作用
    watchEffect(() => {
      console.log(`count is now ${count.value}`);
      // 当 count 发生变化时,这里的代码会被自动执行
    });
    // 使用 watch 观察 count 的变化
    watch(count, (newValue, oldValue) => {
      console.log(`count changed from ${oldValue} to ${newValue}`);
      // 当 count 发生变化时,这里的回调函数会被调用
    });
    // 模拟用户交互,改变 count 的值
    function increment() {
      count.value++;
    }
    return {
      count,
      increment
    };
  }
};

image.gif

       说白了,只要将响应式数据写到watchEffect里面,就能自动侦听变化,并执行一些副作用,这样大大减少了开发时的代码负担。

五、总结

       一篇文章同时搞定Vue2和Vue3的侦听器,是不是很棒?不要忘了Vue3中多了一个可选项watchEffect噢。

       意犹未尽?更多精彩前端好文请关注:各种前端问题的技巧和解决方案

       博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

目录
打赏
0
0
0
0
7
分享
相关文章
vue2和vue3的响应式原理有何不同?
大家好,我是V哥。本文详细对比了Vue 2与Vue 3的响应式原理:Vue 2基于`Object.defineProperty()`,适合小型项目但存在性能瓶颈;Vue 3采用`Proxy`,大幅优化初始化、更新性能及内存占用,更高效稳定。此外,我建议前端开发者关注鸿蒙趋势,2025年将是国产化替代关键期,推荐《鸿蒙 HarmonyOS 开发之路》卷1助你入行。老项目用Vue 2?不妨升级到Vue 3,提升用户体验!关注V哥爱编程,全栈开发轻松上手。
属性描述符初探——Vue实现数据劫持的基础
属性描述符还有很多内容可以挖掘,比如defineProperty与Proxy的区别,比如vue2与vue3实现数据劫持的方式有什么不同,实现效果有哪些差异等,这篇博文只是入门,以后有时间再深挖。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
201 64
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
198 60
初识 Vue(09)---(计算属性、方法、侦听器)
计算属性 计算属性的值是一个函数,并且是内置缓存的; 示例: 计算属性、方法、侦听器 {{fullName}} {{age}} var vm = new Vue({ ...
1168 0
|
3月前
|
vue使用iconfont图标
vue使用iconfont图标
177 1
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
本文介绍了使用 Vue Flow 绘制流程图的方法与技巧。Vue Flow 是一个灵活强大的工具,适合自定义复杂的流程图。文章从环境要求(Node.js v20+ 和 Vue 3.3+)、基础入门案例、自定义功能(节点与连线的定制、事件处理)到实际案例全面解析其用法。重点强调了 Vue Flow 的高度灵活性,虽然预定义内容较少,但提供了丰富的 API 支持深度定制。同时,文中还分享了关于句柄(handles)的使用方法,以及如何解决官网复杂案例无法运行的问题。最后通过对比 mermaid,总结 Vue Flow 更适合需要高度自定义和复杂需求的场景,并附带多个相关技术博客链接供进一步学习。
Vue Router 核心原理
Vue Router 是 Vue.js 的官方路由管理器,用于实现单页面应用(SPA)的路由功能。其核心原理包括路由配置、监听浏览器事件和组件渲染等。通过定义路径与组件的映射关系,Vue Router 将用户访问的路径与对应的组件关联,支持哈希和历史模式监听 URL 变化,确保页面导航时正确渲染组件。
ry-vue-flowable-xg:震撼来袭!这款基于 Vue 和 Flowable 的企业级工程项目管理项目,你绝不能错过
基于 Vue 和 Flowable 的企业级工程项目管理平台,免费开源且高度定制化。它覆盖投标管理、进度控制、财务核算等全流程需求,提供流程设计、部署、监控和任务管理等功能,适用于企业办公、生产制造、金融服务等多个场景,助力企业提升效率与竞争力。
117 12