【愚公系列】《循序渐进Vue.js 3.x前端开发实践》011-Vue 组件的属性和方法:计算属性和侦听器

举报
愚公搬代码 发表于 2024/11/30 23:51:59 2024/11/30
【摘要】 标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。博客内容.NET、...
标题 详情
作者简介 愚公搬代码
头衔 华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。
近期荣誉 2022年度博客之星TOP2,2023年度博客之星TOP2,2022年华为云十佳博主,2023年华为云十佳博主等。
博客内容 .NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
欢迎 👍点赞、✍评论、⭐收藏

🚀前言

在现代前端开发中,Vue.js 作为一款流行的框架,已经成为构建用户界面的重要工具。它通过组件化的方式,使得开发者能够高效地管理复杂的界面和逻辑。在 Vue 组件中,属性和方法是核心概念,而计算属性和侦听器更是实现动态交互和数据响应的重要工具。

本文将深入探讨 Vue 组件中的计算属性和侦听器,帮助你理解它们的工作原理及应用场景。我们将通过实例分析,揭示如何利用这两个特性来提升应用的性能与可维护性。不论你是 Vue 的新手,还是希望深化理解的开发者,相信在阅读本篇文章后,你会对计算属性和侦听器有更清晰的认识,并能够灵活运用它们来优化你的组件设计。准备好了吗?让我们一起探索 Vue 的魅力吧!

🚀一、计算属性和侦听器

大多数情况下,我们都可以将 Vue 组件中定义的属性数据直接渲染到 HTML 元素上,但是有些场景下,属性中的数据并不适合直接渲染,需要我们处理后再进行渲染。在Vue中,通常使用计算属性或侦听器来实现这种逻辑。

🔎1.计算属性

在Vue 3中,计算属性(computed properties)是一种用于声明性地计算和缓存复杂逻辑结果的属性。计算属性依赖于其他响应式数据,在这些依赖的数据发生变化时,计算属性会自动更新。与方法不同的是,计算属性具有缓存功能,只有在依赖的数据改变时才会重新计算,这样可以提高性能。

🦋1.1 计算属性的使用

在Vue 3中,计算属性通常使用computed函数来定义,通常用于在模板中展示依赖多个数据的复杂计算结果。

示例

假设有一个组件需要计算用户的全名,可以使用计算属性来完成:

import { ref, computed } from 'vue';

export default {
  setup() {
    const firstName = ref('John');
    const lastName = ref('Doe');

    // 定义计算属性 fullName
    const fullName = computed(() => {
      return `${firstName.value} ${lastName.value}`;
    });

    return { firstName, lastName, fullName };
  }
};

在模板中,fullName可以直接使用,不需要再调用它,因为计算属性会在依赖的firstNamelastName改变时自动更新:

<template>
  <div>
    <p>First Name: <input v-model="firstName" /></p>
    <p>Last Name: <input v-model="lastName" /></p>
    <p>Full Name: {{ fullName }}</p> <!-- 自动更新 -->
  </div>
</template>

🦋1.2 计算属性的 Getter 和 Setter

计算属性在Vue 3中可以有gettersetter。默认情况下,计算属性只定义getter,即一个用于计算值的函数。如果需要对计算属性进行赋值操作,可以定义setter

示例:双向绑定的计算属性

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed({
  get() {
    return `${firstName.value} ${lastName.value}`;
  },
  set(newValue) {
    const names = newValue.split(' ');
    firstName.value = names[0];
    lastName.value = names[1];
  }
});

通过这样定义的计算属性,既可以读取fullName的值,也可以对其进行赋值操作:

<template>
  <div>
    <p>Full Name: <input v-model="fullName" /></p> <!-- 可双向绑定 -->
  </div>
</template>

🔎2.使用计算属性还是函数

选择使用计算属性还是函数,取决于具体的需求和场景。以下是两者的对比,可以帮助你做出选择:

🦋2.1 计算属性computed

计算属性适用于依赖响应式数据且需要缓存的情况。它在依赖的响应式数据(如refreactive)没有变化时,不会重新计算,可以提高性能。

适用场景

  • 需要基于其他响应式数据进行计算。
  • 计算结果会频繁在模板中使用。
  • 结果在依赖的数据未变化时不需要重新计算。

示例

import { ref, computed } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`;
});

在模板中:

<template>
  <div>
    <p>Full Name: {{ fullName }}</p>
  </div>
</template>

🦋2.2 函数methods 或 直接在 setup 中定义的函数)

函数每次调用时都会重新执行,不会缓存结果。函数适合用于不会影响性能的简单计算,或在模板中不会频繁使用的情况。

适用场景

  • 不需要缓存结果,或者每次都希望重新计算。
  • 逻辑较为简单,不依赖于其他响应式数据。
  • 仅在某些特定交互事件中使用,或仅调用一次。

示例

import { ref } from 'vue';

const firstName = ref('John');
const lastName = ref('Doe');

function getFullName() {
  return `${firstName.value} ${lastName.value}`;
}

在模板中:

<template>
  <div>
    <p>Full Name: {{ getFullName() }}</p> <!-- 每次访问都会重新计算 -->
  </div>
</template>

🦋2.3 什么时候选择计算属性?

  1. 需要缓存:计算属性会缓存值,直到依赖的响应式数据发生变化。如果是复杂的计算逻辑,或这个值会被频繁访问,计算属性可以避免不必要的重新计算。
  2. 提高可读性:计算属性通常简化了模板中的表达式,使模板更易读。

🦋2.4 什么时候选择函数?

  1. 不需要缓存:如果计算量非常小,且不需要缓存结果,直接使用函数更简单。
  2. 用于事件响应:函数可以直接作为事件处理器来调用,避免在事件处理程序中额外的复杂性。

🦋2.5 总结

  • 频繁使用、依赖其他数据且需要缓存:使用计算属性。
  • 偶尔调用、不需要缓存、或用于事件:使用函数。

在Vue应用中,这两个特性都很重要,但一般优先使用计算属性来保持模板的简洁和性能的优化。

🔎3.计算属性的赋值

在Vue中,计算属性通常只用来读取计算后的值。但如果需要对计算属性进行赋值操作,可以通过定义带有getter和setter的计算属性来实现双向绑定。这样可以实现赋值时自动更新计算属性所依赖的数据。

🦋3.1 计算属性的Getter和Setter

在Vue 3中,可以使用computed函数来定义带有getter和setter的计算属性。getter负责读取计算属性的值,而setter负责在计算属性被赋值时执行特定的逻辑,从而修改其他响应式数据。

示例:双向绑定的计算属性

假设有两个数据属性firstNamelastName,希望通过计算属性fullName来计算全名,并允许直接对fullName进行赋值,自动更新firstNamelastName

JavaScript代码

import { ref, computed } from 'vue';

export default {
  setup() {
    const firstName = ref('John');
    const lastName = ref('Doe');

    // 定义带有getter和setter的计算属性 fullName
    const fullName = computed({
      get() {
        return `${firstName.value} ${lastName.value}`;
      },
      set(newValue) {
        const names = newValue.split(' ');
        firstName.value = names[0];
        lastName.value = names[1];
      }
    });

    return { firstName, lastName, fullName };
  }
};

在这个例子中:

  • Getter返回firstNamelastName的组合,即全名。
  • Setter接收新赋的值newValue,并将其按空格分开更新firstNamelastName的值。

🔎4.属性侦听器

属性侦听器(watchers)是Vue中的一种功能,用于监听特定响应式属性的变化,并在属性值发生变化时执行相应的操作。属性侦听器尤其适合处理副作用(如异步请求、手动更新数据)和监控属性变化。

🦋4.1 使用属性侦听器的场景

属性侦听器在以下场景中非常有用:

  1. 需要在某个属性变化时执行特定逻辑,而不是在模板中显示计算结果。
  2. 处理复杂或异步的操作,如在属性变化时触发API请求。
  3. 当依赖多层级数据(嵌套对象或数组)时,对特定属性的变化进行监控。

🦋4.2 属性侦听器的基本用法

在Vue 3的Composition API中,可以通过watch函数来创建属性侦听器。

示例代码
假设有一个searchText属性,当它变化时希望进行一些处理,比如监控输入文本的长度,如果超过10字符则发出警告。

import { ref, watch } from 'vue';

export default {
  setup() {
    const searchText = ref('');

    // 监听 searchText 属性的变化
    watch(searchText, (newValue, oldValue) => {
      console.log(`新值: ${newValue}, 旧值: ${oldValue}`);
      if (newValue.length > 10) {
        alert('输入的文本太长了!');
      }
    });

    return { searchText };
  }
};

在这个示例中:

  • watch接收两个参数:要监听的属性searchText和一个回调函数。
  • 回调函数在searchText变化时执行,接收两个参数,分别是newValue(新值)和oldValue(旧值)。

🦋4.3 监听多个属性

你可以在一个属性侦听器中监听多个属性,或者使用多个watch函数分别监听不同属性的变化。

const firstName = ref('John');
const lastName = ref('Doe');

watch([firstName, lastName], ([newFirstName, newLastName], [oldFirstName, oldLastName]) => {
  console.log(`名字从${oldFirstName} ${oldLastName}变为${newFirstName} ${newLastName}`);
});

在这里,通过数组形式可以同时监听firstNamelastName,回调函数会在任意一个属性变化时触发。

🦋4.4 深度监听(Deep Watch)

默认情况下,watch只会监听对象或数组的第一层级。如果要监听嵌套对象或数组的深层级变化,可以在watch中传入{ deep: true }选项。

const user = ref({
  name: 'Alice',
  profile: {
    age: 25
  }
});

watch(user, (newValue, oldValue) => {
  console.log("User profile changed:", newValue);
}, { deep: true });

在这个例子中,{ deep: true }选项使得watch可以监听user.profile.age等深层次的属性变化。

🦋4.5 配置选项

属性侦听器的watch函数还可以接收一些配置选项:

  1. immediate:立即执行回调函数(即在侦听器注册时就执行一次)。

    watch(searchText, (newValue) => {
      console.log("Search Text changed:", newValue);
    }, { immediate: true });
    
  2. deep:深度监听,用于监听对象内部属性的变化(递归监听对象或数组中的嵌套属性)。

    const data = ref({ items: [1, 2, 3] });
    
    watch(data, (newValue) => {
      console.log("Data changed:", newValue);
    }, { deep: true });
    

在这里插入图片描述

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。