Vue 2教程:理解和应用watch侦听器与computed计算属性

1、watch 侦听器

1.1 什么是 watch 侦听器

watch 侦听器 允许开发者监视数据的变化,从而 针对数据的变化做特定的操作
语法格式如下:
 const vm = new Vue({
      el: '#app',
      data: {
        username: 'admin'
      },
      // 所有的侦听器,都应该被定义到 watch 节点下
      watch: {
        // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
        // newVal是变化后的“新值”,newVal是变化前的“旧值”
        username(newVal,oldval) {
          console.log(newVal,oldval)
        }
      }
    })

1.2 使用 watch 检测用户名是否可用

监听 username 值的变化,并使用 axios 发起 Ajax 请求, 检测当前输入的用户名是否可 用:
  // 所有的侦听器,都应该被定义到 watch 节点下
      watch: {
        // 侦听器本质上是一个函数,要监视哪个数据的变化,就把数据名作为方法名即可
        // 新值在前,旧值在后
        username(newVal) {
          if (newVal === '') return
          // 1. 调用 jQuery 中的 Ajax 发起请求,判断 newVal 是否被占用!!!
          $.get('https://www.escook.cn/api/finduser/' + newVal, function (result) {
            console.log(result)
          })
        }
      }

1.3 immediate 选项

默认情况下,组件在初次加载完毕后不会调用 watch 侦听器。如果想让 watch 侦听器 立即被调用 ,则需要使用 immediate 选项。示例代码如下:
  watch: {
        username: {
          // handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
          handler: async function (newVal) {
            if (newVal === '') return
            const { data: res } = await axios.get('https://www.escook.cn/api/finduser/' + newVal)
            console.log(res)
          },
          // 表示页面初次渲染好之后,就立即触发当前的 watch 侦听器
          immediate: true
        }
      }

1.4 deep 选项

如果 watch 侦听的是一个对象 ,如果 对象中的属性值发生了变化 ,则 无法被监听到 。此时需要使用 deep 选项 ,代码示例如下
data:{
  info:{username:'admin'}
},
watch: {
        info: {
          // handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
          handler(newVal) {
            console.log(newVal.username);
          },
          // 表示开启深度监听
          deep: true,
        }
      }

1.5 监听对象单个属性的变化

如果 只想监听对象中单个属性的变化 ,则可以按照如下的方式定义 watch 侦听器:
data:{
  info:{username:'admin'}
},
watch: {
        'info.username': {
          // handler 是固定写法,表示当 username 的值变化时,自动调用 handler 处理函数
          handler(newVal) {
            console.log(newVal);
          }
        }
      }

2、computed 计算属性

2.1 什么是计算属性

计算属性指的是 通过一系列运算 之后,最终得到一个 属性值
这个动态计算出来的属性值 可以被模板结构或 methods 方法使用。示例代码如下:
   <style>
    .box {
      width: 200px;
      height: 200px;
      border: 1px solid #ccc;
    }
  </style>
 
<div id="app">
    <div>
      <span>R:</span>
      <input type="text" v-model.number="r">
    </div>
    <div>
      <span>G:</span>
      <input type="text" v-model.number="g">
    </div>
    <div>
      <span>B:</span>
      <input type="text" v-model.number="b">
    </div>
    <hr>

    <!-- 专门用户呈现颜色的 div 盒子 -->
    <!-- 在属性身上,: 代表  v-bind: 属性绑定 -->
    <!-- :style 代表动态绑定一个样式对象,它的值是一个 {  } 样式对象 -->
    <!-- 当前的样式对象中,只包含 backgroundColor 背景颜色 -->
    <div class="box" :style="{ backgroundColor: rgb }">
      {{ rgb }}
    </div>
    <button @click="show">按钮</button>
  </div>

  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        // 红色
        r: 0,
        // 绿色
        g: 0,
        // 蓝色
        b: 0
      },
      methods: {
        // 点击按钮,在终端显示最新的颜色
        show() {
          console.log(this.rgb)
        }
      },
      // 所有的计算属性,都要定义到 computed 节点之下
      // 计算属性在定义的时候,要定义成“方法格式”
      computed: {
        // rgb 作为一个计算属性,被定义成了方法格式,
        // 最终,在这个方法中,要返回一个生成好的 rgb(x,x,x) 的字符串
        rgb() {
          return `rgb(${this.r}, ${this.g}, ${this.b})`
        }
      }
    });

    console.log(vm)
  </script>

2. 2计算属性的特点

① 虽然计算属性在 声明的时候 被定义为 方法 ,但是计算属性的 本质是一个属性
② 计算属性会 缓存计算的结果 ,只有计算属性 依赖的数据变化时 ,才会重新进行运算

3、watch 侦听器 与 computed 计算属性的区别

区别

  1. 功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。
  2. 是否调用缓存:computed 中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调
  3. 是否调用 return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。
  4. computed默认第一次加载的时候就开始监听;watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true(immediate:true)  

计算属性 vs 侦听器

计算属性和侦听器 侧重的应用场景不同
计算属性侧重于监听 多个值 的变化,最终计算并 返回一个新值
侦听器侧重于监听 单个数据 的变化,最终 执行特定的业务处理,不需要有任何返回值

使用场景:

    computed 计算属性: 当一个属性受多个属性影响的时候

      例如:购物车商品结算,只要购买数量,购买价格,优惠券,折扣券等任意一个发生变化,总价都会        自动跟踪变化.

代码:

  computed:{
     // 已勾选的商品的总价
       checkedGoodsAmount(state) {
         // 先使用 filter 方法,从购物车中过滤器已勾选的商品
         // 再使用 reduce 方法,将已勾选的商品数量 * 单价之后,进行累加
         // reduce() 的返回值就是已勾选的商品的总价
         // 最后调用 toFixed(2) 方法,保留两位小数
         return state.cart.filter(x => x.goods_state)
                          .reduce((total, item) => total += item.goods_count * item.goods_price, 0)
                          .toFixed(2)
       }
}

 总结:

  1. 模板中的表达式简洁易维护
  2. 根据传入的变量的变化进行处理更新结果
  3. 计算属性属于响应式依赖进行缓存,如果其中的没有值改变,则它调用的就是上一次 计算缓存的数据,因此提高了性能

watch 侦听器:当需要在数据变化时执行异步或开销较大的 操作时,这个方式是最有用的。

例如:搜索框,当一条数据影响多条数据的时候,使用watch

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狗蛋的博客之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值