当前位置: 首页 > news >正文

vue入门:计算属性computer监听器watch

文章目录

  • 计算属性computer
    • 定义计算属性
    • 在模板中使用计算属性
    • 计算属性的使用场景
  • 监听器watch
    • 基本语法
    • 深度监听
    • 立即执行
    • 监听数组
    • 异步操作
    • 数据校验
    • 副作用处理
    • 清理监听器
  • watch 与 computed 的区别

计算属性computer

在 Vue 中,计算属性(computed)是一种非常强大的功能,它允许你基于组件的响应式数据动态计算新的值。计算属性是基于它们的依赖进行缓存的,只有当依赖发生变化时,计算属性才会重新计算。这使得计算属性比普通的方法更加高效,尤其是在处理复杂逻辑或性能敏感的场景时。

Vue 的响应式系统会追踪计算属性的依赖。当计算属性的依赖发生变化时,计算属性会自动重新计算。依赖追踪是基于 Vue 的响应式系统实现的,它能够高效地检测依赖的变化

new Vue({
  el: '#app',
  data: {
    a: 1,
    b: 2
  },
  computed: {
    c() {
      return this.a + this.b;
    }
  }
});

在这个例子中,c 是一个计算属性,它依赖于 a 和 b。当 a 或 b 的值发生变化时,c 会自动重新计算。

定义计算属性

计算属性通过 computed 选项定义,它是一个对象,对象的每个属性对应一个计算逻辑。计算属性可以是一个函数,也可以是一个包含 get 和 set 方法的对象

new Vue({
  el: '#app',
  data: {
    firstName: 'John',
    lastName: 'Doe'
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }
});

fullName 是一个计算属性,它基于 firstName 和 lastName 的值动态计算出完整的姓名。当 firstName 或 lastName 发生变化时,fullName 会自动重新计算

在模板中使用计算属性

<div id="app">
  <p>First Name: <input v-model="firstName"></p>
  <p>Last Name: <input v-model="lastName"></p>
  <p>Full Name: {{ fullName }}</p>
</div>

计算属性的使用场景

  1. 数据格式化
new Vue({
  el: '#app',
  data: {
    date: new Date()
  },
  computed: {
    formattedDate() {
      return this.date.toISOString().split('T')[0];
    }
  }
});

formattedDate 是一个计算属性,它将 date 格式化为 YYYY-MM-DD 的格式。

  1. 复杂逻辑计算
new Vue({
  el: '#app',
  data: {
    items: [
      { name: 'Item 1', price: 10, quantity: 2 },
      { name: 'Item 2', price: 20, quantity: 3 }
    ]
  },
  computed: {
    totalPrice() {
      return this.items.reduce((total, item) => total + item.price * item.quantity, 0);
    }
  }
});

totalPrice 是一个计算属性,它基于 items 数组计算购物车的总价。

  1. 条件渲染
new Vue({
  el: '#app',
  data: {
    user: {
      role: 'admin'
    }
  },
  computed: {
    isAdmin() {
      return this.user.role === 'admin';
    }
  }
});

isAdmin 是一个计算属性,它基于 user.role 的值动态计算用户是否为管理员

监听器watch

在 Vue 中,watch 是一个非常强大的功能,用于监听组件数据的变化,并在数据发生变化时执行特定的逻辑。与计算属性(computed)相比,watch 提供了更灵活的响应机制,可以执行更复杂的操作,包括异步操作和副作用。

watch 可以监听组件中的数据属性或计算属性,并在它们发生变化时执行回调函数。

基本语法

  • 数据属性
new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!',
    b: { c: 2, d: 3 },
  },
  watch: {
    message(newVal, oldVal) {
      console.log(`Message changed from ${oldVal} to ${newVal}`);
    },
    
    "b.c": function(val, oldVal) {
      this.b.d += 1;
      console.log("new: %s, old: %s", val, oldVal);
    },
    
  }
});

watch 监听了 message 属性。当 message 的值发生变化时,会调用回调函数,newVal 是新值,oldVal 是旧值。

  • 计算属性
new Vue({
  el: '#app',
  data: {
    firstName: 'John',
    lastName: 'Doe'
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  },
  watch: {
    fullName(newVal, oldVal) {
      console.log(`Full Name changed from ${oldVal} to ${newVal}`);
    }
  }
});

watch 监听了计算属性 fullName。当 firstNamelastName 的值发生变化时,fullName 会重新计算,watch 会捕获到这个变化并执行回调函数。

深度监听

默认情况下,watch 是浅监听,只监听对象的第一层属性变化。如果需要监听对象的深层属性变化,可以使用 deep 选项。

new Vue({
  el: '#app',
  data: {
    user: {
      name: 'John',
      age: 30
    }
  },
  watch: {
    user: {
      handler(newVal, oldVal) {
        console.log(`User changed from ${JSON.stringify(oldVal)} to ${JSON.stringify(newVal)}`);
      },
      deep: true
    }
  }
});

watch 使用了 deep 选项来深度监听 user 对象。当 user 对象的任何属性(如 name 或 age)发生变化时,都会触发回调函数.

立即执行

默认情况下,watch 的回调函数只有在监听的数据发生变化时才会执行。如果需要在组件初始化时立即执行回调函数,可以使用 immediate 选项.

new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message: {
      handler(newVal, oldVal) {
        console.log(`Message changed from ${oldVal} to ${newVal}`);
      },
      immediate: true
    }
  }
});

watch 使用了 immediate 选项。组件初始化时,message 的值会被传递给回调函数,即使它没有发生变化。

监听数组

watch 也可以监听数组的变化,但需要注意数组的响应式操作。

new Vue({
  el: '#app',
  data: {
    items: [1, 2, 3]
  },
  watch: {
    items: {
      handler(newVal, oldVal) {
        console.log(`Items changed from ${oldVal} to ${newVal}`);
      },
      deep: true
    }
  }
});

watch 监听了 items 数组。当数组的元素发生变化时,会触发回调函数。需要注意的是,直接通过索引修改数组元素(如 this.items[0] = 4)不会触发响应式更新,应该使用 Vue 提供的数组方法(如 push, splice 等)来确保响应性。

watch 的应用场景

异步操作

new Vue({
  el: '#app',
  data: {
    userId: 1
  },
  watch: {
    userId(newVal, oldVal) {
      this.fetchUserData(newVal);
    }
  },
  methods: {
    fetchUserData(userId) {
      fetch(`https://api.example.com/users/${userId}`)
        .then(response => response.json())
        .then(data => {
          console.log(data);
        });
    }
  }
});

当 userId 的值发生变化时,会调用 fetchUserData 方法从服务器获取用户数据。

数据校验

new Vue({
  el: '#app',
  data: {
    email: ''
  },
  watch: {
    email(newVal) {
      if (!this.validateEmail(newVal)) {
        alert('Invalid email address');
      }
    }
  },
  methods: {
    validateEmail(email) {
      const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return re.test(email);
    }
  }
});

副作用处理

watch 可以用于处理副作用,例如在数据变化时更新 DOM 或调用第三方库。

new Vue({
  el: '#app',
  data: {
    count: 0
  },
  watch: {
    count(newVal) {
      document.title = `Count is ${newVal}`;
    }
  }
});

当 count 的值发生变化时,会更新浏览器的标题。

清理监听器

在组件销毁时,清理不必要的监听器,避免内存泄漏。

new Vue({
  el: '#app',
  data: {
    message: 'Hello, Vue!'
  },
  watch: {
    message: {
      handler(newVal, oldVal) {
        console.log(`Message changed from ${oldVal} to ${newVal}`);
      },
      immediate: true
    }
  },
  beforeDestroy() {
    this.$watchers.message.teardown();
  }
});

在这个例子中,使用 beforeDestroy 生命周期钩子清理了 message 的监听器。

watch 与 computed 的区别

  1. computed:基于依赖进行缓存,只有当依赖发生变化时才会重新计算。计算属性是同步的,适合用于简单的数据计算。
  2. watch:提供更灵活的响应机制,可以执行异步操作和副作用。watch 的回调函数在数据变化时立即执行,适合用于复杂的逻辑处理。
  3. 能使用计算属性 computed 实现的的,则尽量使用 computed 属性来实现。

相关文章:

  • 智慧农业整体解决方案
  • AF3 ProteinDataset类的__getitem__方法解读
  • 论文笔记——KIMI-VL:具有增强推理能力的有效开源视觉语言模型
  • 从0到1使用C++操作MSXML
  • 在 Spring Boot 中实现服务器端推送(SSE):两种方法的比较与实践
  • MySQL事务机制
  • GPT-4、Grok 3与Gemini 2.0 Pro:三大AI模型的语气、风格与能力深度对比
  • H5:实现安卓和苹果点击下载App自动跳转到对应的应用市场
  • 【C#】CAN通信的使用
  • STM32 HAL 库开发之通用定时器中断
  • Linux中的文件传输(附加详细实验案例)
  • [MRCTF2020]ezpop wp
  • CSI-PVController
  • 面向对象编程基础:从方法论到实践的全面解析
  • 【BEPU V1物理】BEPUphysics v1 入门指南 汉化笔记#1
  • JavaScript 基础语法系统学习笔记
  • 使用MPI-IO并行读写HDF5文件
  • 操作系统简要概述
  • 深入解析 Android 图形系统:Canvas、Skia、OpenGL 与 SurfaceFlinger 的协作
  • Vue 3 自定义指令
  • 黑龙江省政府副秘书长许振宇,拟任正厅级领导
  • 中国证券业协会修订发布《证券纠纷调解规则》
  • 由我国牵头制定,适老化数字经济国际标准发布
  • 观察|本轮印巴冲突或促使印度空军寻求更先进战机
  • 腾讯一季度营收增长13%,马化腾:战略性的AI投入将带来长期回报
  • 习近平会见哥伦比亚总统佩特罗