一文弄清楚Vue中的computed与watch的区别

news2025/1/16 7:58:46

1.实现业务

当我们点击按钮,就会切换h1标签的语句内容,再次点击按钮,h1标签的语句内容就会恢复,每次点击按钮,浏览器都会输出一个语句来表达监视到了h1的内容改变

2.Vue中的computed计算属性

2.1利用Vue中的computed计算属性实现业务

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <!-- 因为info是一个计算属性,所以当Vue初次解析模板是就会输出info的返回值 -->
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="isHot = !isHot">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el:'#root',
      data:{
        isHot: true // 作为info的变化媒介
      },
      computed:{
        info(){
          console.log('@----','isHot改变了') // 这里用于体现监听效果
          return this.isHot ? '炎热' : '凉爽'
        }
      }
    })
  </script>
</body>

上面注意一个小点,就是在事件绑定的时候,处理值可以是一些简单的执行语句,其余情况还是用方法调用的方式比较友好,上面代码等同于下面代码

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el:'#root',
      data:{
        isHot: true
      },
      methods: {
        changeWeather(){ // 将事件绑定的执行语句放到方法里面,之后再事件绑定中去调用该方法就行了
          this.isHot = !this.isHot
        }
      },
      computed:{
        info(){
          console.log('@----','isHot改变了')
          return this.isHot ? '炎热' : '凉爽'
        }
      }
    })
  </script>
</body>

2.2Vue中的computed计算属性存在的问题

问题一

例如,我现在业务又要求,我想在一秒之后去再去改变h1标签里面的内容

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el:'#root',
      data:{
        isHot: true
      },
      methods: {
        changeWeather(){
          this.isHot = !this.isHot
        }
      },
      computed:{
        info(){
          console.log('@----','isHot改变了')
          setTimeout(() => { // 给info添加一个定时器,让其一秒钟之后才会有返回值
            return this.isHot ? '炎热' : '凉爽'
          },1000)
        }
      }
    })
  </script>
</body>

你会发现,初始化的时候值就不能被展示出来,且点击按钮过了一秒之后依旧没反应,但是不报错

问题二

例如,我现在又要把业务进行扩展,我需要在监听的时候,将新值和旧值一同展示出来

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el:'#root',
      data:{ // data属性中新舔两个属性,一个是新值,一个是旧值
        isHot: true,
        newValue: '炎热',
        oldValue: '凉爽'
      },
      methods: {
        changeWeather(){
          this.isHot = !this.isHot
        }
      },
      computed:{
        info(){ // 计算属性里面进行处理,展现监听isHot变化,并且同时展示旧值、新值的效果
          console.log('@----',`今天的天气很${this.newValue},昨天天气很${this.oldValue}`);
          let passValue = this.newValue;
          this.newValue = this.oldValue;
          this.oldValue = passValue;
          return this.isHot ? passValue : this.oldValue
        }
      }
    })
  </script>
</body>

你会发现这样子做下来,代码显得很繁琐,新值和旧值还需要自己在data属性里面添加,无缘无故增加了Vue的负担

3.Vue中的watch监听属性

3.1Vue中的watch监听属性是什么?

Vue中可以使用监听器监听已有属性的变化(监听了未定义的属性也不会报错),并根据属性的变化作出响应。

3.2Vue中的watch监听属性的基本使用方式

  • watch监听属性下可以有多个监听对象,每一个监听对象中都有一个handler函数,该函数有两个参数,第一个参数为监听对象改变前的值,第二个参数为监听对象改变后的旧值

  • 两个参数都不是必须的,需要用时用就好了

  • handler函数在监听对象发生改变时触发

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el: '#root',
      data: {
        isHot: true,
      },
      methods: {
        changeWeather() {
          this.isHot = !this.isHot
        }
      },
      computed:{
        info(){
          return this.isHot ? '炎热' : '凉爽'
        }
      },
      watch: {
        info:{ // info就是需要监听的对象
          handler(newValue,oldValue){
            console.log('@----',`今天的天气很${newValue},昨天的天气很${oldValue}`)
          }
        }
      }
    })
  </script>
</body>

我们仔细观察上面的动态图片会发现,我们点击按钮之前,浏览器的日志输出是空的,说明Vue没有在一开始的时候就去解析watch监听属性(有别于computed计算属性)

注意:

当我们给监听对像添加立即执行的额外配置(immediate:true)时,我们就会发现Vue会在一开始就去解析watch监听属性

watch: {
  info:{ // info就是需要监听的对象
    immediate:true,
    handler(newValue,oldValue){
      console.log('@----',`今天的天气很${newValue},昨天的天气很${oldValue}`)
    }
  }
}

我们可以看到,当给监听对象加上立即执行的额外配置(immediate:true)时,浏览器的日志输出在一开始就会有输出内容,也就是说Vue会在一开始就去解析watch监听属性,但是你会发现此时的oldValue值为undefined

3.3watch监听的深度监听

如果需要深度监听,必须给监听对象额外进行允许深度监听的配置(deep:true),该配置可以让Vue的负担减轻,因为不是每一个监听对象都需要进行深度监听,当我们需要深度监听的时候,我们手动配置就好了

未给watch配置深度监听
给watch配置了深度监听
<script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el: '#root',
      data: {
        obj: { // 用于深度监听测试
          a : {
            b : {
              c : {
                d: 20
              }
            }
          }
        }
      },
      watch: {
        obj:{
          deep:true, // 这是watch监听属性能深度监听属性的关键
          handler(){
            console.log('@----','obj发生了改变');
          }
        }
      }
    })
  </script>

给watch配置了深度监听

3.4Vue中的监听属性另外的写法

语法格式
vm.$watch(监听对象,回调函数) // 监听对象需要打引号,回调函数包含两个参数
利用该语法实现业务
<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">改变天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el: '#root',
      data: {
        isHot:true
      },
      methods: {
        changeWeather(){
          this.isHot = !this.isHot
        }
      },
      computed: {
        info(){
          return this.isHot ? '炎热' : '凉爽'
        }
      }
    })
    vm.$watch('info',function(newValue,oldValue){
      console.log(`今天的天气很${newValue},昨天的天气很${oldValue}`)
    })
  </script>
</body>

3.5Vue中的watch监听属性的简写方式

当我们不需要给watch的监听对象进行额外配置时,我们才可以使用watch的简写形式,简写形式相当于就是将监听对象和handler函数融为一起了

不是简写形式
watch: {
  info:{ // info就是需要监听的对象
    handler(newValue,oldValue){
      console.log('@----',`今天的天气很${newValue},昨天的天气很${oldValue}`)
    }
  }
}
简写形式
watch: {
  info(newValue,oldValue){
    console.log('@----',`今天的天气很${newValue},昨天的天气很${oldValue}`)
  }
}

3.6利用Vue中的watch监听属性来实现业务

<body>
  <!-- 给一个容器 -->
  <div id="root">
    <h1>今天的天气很{{info}}</h1>
    <!-- 事件绑定时:@xxx="yyy" yyy可以是一些简单的语句 -->
    <button @click="changeWeather">切换天气</button>
  </div>
  <script>
    Vue.config.productionTip = false; // config是Vue的配置选项,这里表示不让vue产生额外的提示信息
    const vm = new Vue({
      el: '#root',
      data: {
        isHot: true,
      },
      methods: {
        changeWeather() {
          this.isHot = !this.isHot
        }
      },
      computed:{
        info(){
          return this.isHot ? '炎热' : '凉爽'
        }
      },
      watch: {
        info:{ // info就是需要监听的对象
          handler(newValue,oldValue){ 
            setTimeout(() => { // 过一秒钟之后才会提示监听信息,完成了异步任务
              console.log('@----',`今天的天气很${newValue},昨天的天气很${oldValue}`) // 很容易拿到新值、旧值
            },1000)
          }
        }
      }
    })
  </script>
</body>

当我们观察上面现象就可以发现,利用Vue的watch监听属性可以很好的处理异步任务,并且很简单那的就能拿到新值、旧值,这两点也很好的解决了刚才使用Vue的computed计算属性去完成业务所出现的问题

注意:

上面使用定时函数setTimeout的时候,我们使用的是箭头函数,为什么这个时候使用箭头函数?因为如果是普通函数,那么JS认定setTimeout函数就是Window调用的,所以setTimeout中的this会指向Window,而如果用箭头函数,那么箭头函数是没有自己的this的,所以这个时候的this指向handler函数的this,所以在Vue中,我们定义函数时一定要考虑清楚this的指向问题

4.总结

  • computed能完成的功能,watch都可以完成

  • watch能完成的功能,computed不一定能够完成,例如:watch可以进行异步操作

  • 被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象

  • 所以不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows server——部署DHCP服务

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 本章重点 一.DHCP概述 1.DHCP服务的好处 二.DHCP的工作原理 1.DHCP的分配方…

【云原生 | 50】Docker三剑客之Docker Compose第一节

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

pinia和vuex的区别

pinia和vuex的区别 什么是“状态管理模式”&#xff1f; const Counter {// 状态data () {return {count: 0}},// 视图template: <div>{{ count }}</div>,// 操作methods: {increment () { this.count}} }createApp(Counter).mount(#app)这个状态自管理应用包含…

字符串题记

经典字符串leetcode题 文章目录经典字符串leetcode题反转字符串第一种方法&#xff1a;使用string里的库函数reverse第二种方法&#xff1a;使用自己写的swap函数第一种swap函数第二种swap函数151.翻转字符串里的单词28. 实现 strStr()KMP算法459.重复的子字符串第一种&#xf…

UE4 后期材质节点学习

以下对应的效果&#xff1a; 材质后期在这里进行设置&#xff1a; 在这里调整场景的整体的饱和度 场景的对比度 灰度系数的调整 高光度/图像增益 灰阶偏移的设置 想了解这些专业名词可以看&#xff1a;相机gain lift gamma offset参数意义_baobei0112的博客-CSDN博客_相机gai…

Redis学习笔记(一)Linux下安装部署Redis

一、下载Redis 1、进入官网&#xff0c;进入download页面 https://redis.io/download&#xff0c;找到“List of all releases and hash digests”&#xff0c;点击“ listing of all previous Redis releases on the releases page”&#xff0c;可以进入所有版本下载页面。 …

STM32——DMA直接存储器访问

文章目录一、DMA直接存储器存取DMA简介二、存储器映像三、DMA框图四、DMA基本结构五、DMA请求&#xff08;触发源&#xff09;六、数据宽度与对齐七、存储器到存储器的DMA转运原理图关键代码八、外设到存储器的DMA转运原理图硬件链接图关键代码九、其他一、DMA直接存储器存取 …

【图像分类】4.ResNet残差模块卷积网络的神

ResNet重要性不必多说了吧&#xff0c;论文引用破10w&#xff0c;是我见过最多的&#xff0c;yyds&#xff01; 在对照博主霹雳吧啦和官方pytorch的代码下&#xff0c;手撸一个resnet。如果没有看着代码写&#xff0c;不确定自己是否能根据论文写出model&#xff0c;而且写优雅…

java学习day69(乐友商城)用户注册

今日目标&#xff1a; 创建用户中心 了解面向接口开发方式 实现数据校验功能 实现短信发送功能 实现注册功能 实现根据用户名和密码查询用户功能 1.创建用户中心 用户搜索到自己心仪的商品&#xff0c;接下来就要去购买&#xff0c;但是购买必须先登录。所以接下来我们编…

STM32MP157驱动开发——Linux IIO驱动(下)

STM32MP157驱动开发——Linux IIO驱动&#xff08;下&#xff09;0.前言一、IIO 触发缓冲区1.IIO 触发器2.申请触发器3.释放触发器4.注册触发器5.注销触发器6. IIO 缓冲区7.向驱动程序添加触发缓冲功能8.驱动编写9.触发缓冲测试10.缓冲区读取二、测试App三、测试结果0.前言 上一…

【C++高阶数据结构】B树、B+树、B*树

&#x1f3c6;个人主页&#xff1a;企鹅不叫的博客 ​ &#x1f308;专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接&#xff1a;代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…

高等数学(第七版)同济大学 习题11-3 (前7题)个人解答

高等数学&#xff08;第七版&#xff09;同济大学 习题11-3&#xff08;前7题&#xff09; 函数作图软件&#xff1a;Mathematica 1.计算下列曲线积分&#xff0c;并验证格林公式的正确性&#xff1a;\begin{aligned}&1. \ 计算下列曲线积分&#xff0c;并验证格林公式的正…

PyTorch深度学习快速入门教程

PyTorch深度学习快速入门教程1、Pytorch加载数据2、Tensorbord的使用3、Transforms的使用4、常见的Transforms5、torchvision中的数据集使用6、DataLoader的使用7、神经网络的基本骨架—nn.module8、卷积操作9、神经网络—卷积层10、神经网络—池化层的使用11、神经网络—非线性…

靴子落地!Mobileye正式启动4D成像雷达量产进程

4D毫米波雷达赛道正在变得越来越拥挤。 在传统雷达时代&#xff0c;全球主要的市场参与者屈指可数&#xff0c;博世、大陆、安波福、海拉等少数几家巨头几乎垄断前装市场。如今&#xff0c;随着4D时代的开启&#xff0c;越来越多的新进入者希望能够实现换道超车&#xff0c;这…

Jar 组件自动化风险监测和升级实践

背景 以 Xstream、Jackson、Fasjson 等为代表的 Jar 组件高危漏洞层出不穷&#xff0c;安全组每年 N 次推动业务线进行第三方 Jar 组件升级&#xff0c;每次升级动辄涉及成百上千个应用服务&#xff0c;给双方都带来了沉重的负担。为了降低安全组在 Jar 组件升级期间的工作量&…

JS 如何利用浏览器的 cookie 保存用户名

前言 浏览器的cookie可以用来存储一些少量的网站信息,比如登录的用户名,用于提高用户体验非常有帮助 有的一些网站在第一次登录后,在指定的时间范围内容,下次在打开网站,再次登录时,不用每次都重新输入用户名的 或在做一些购物车效果时,也可以使用cookie,保持一个状态持续多…

【数据结构与算法——C语言版】3. 二分查找

前言 本文将介绍在线性表查找中非常常用的一种查找算法——二分法&#xff0c;先介绍二分查找法的核心思路&#xff0c;然后进行代码讲解&#xff0c;最终给出二分查找法的时/空复杂度&#xff0c;并比较其和上篇文章【数据结构与算法——C语言版】2. 数组介绍的顺序查找的区别…

神经网络漫谈(一)

神经网络漫谈(一) 发表时间&#xff1a; 2023年1月6日创作地点&#xff1a;湖北省武汉市作者&#xff1a;ixy_com&Bill Kromydas封面图片来源&#xff1a;Towards Data Science 1、背景 基本概念&#xff1a;神经网络&#xff0c;也称为人工神经网络 (ANN) 或模拟神经…

基础数据结构——二叉树

目录 一、二叉树性质 1、满二叉树、完全二叉树 2、平衡二叉树 3、不平衡二叉树 二、二叉树的存储 1、普通做法 2、竞赛做法 三、二叉树的遍历 1、宽度优先遍历 2、深度优先遍历 &#xff08;1&#xff09;先&#xff08;根&#xff09;序遍历 &#xff08;2&#x…

【java中的集合框架】学习接触java中的集合,走上学习数据结构道路

前言&#xff1a; 大家好&#xff0c;我是良辰呀&#x1f3eb;&#x1f3eb;&#x1f3eb;&#xff0c;从今天开始&#xff0c;我们一起来探索数据结构的知识海洋。期待与大家结伴同行&#xff0c;gogogo。&#x1f36c;&#x1f36c;&#x1f36c; &#x1f9d1;个人主页&…