前端Vue日常工作中--computed计算属性

前端Vue日常工作中--computed计算属性

Vue.js 中的计算属性是一种方便的属性,它允许你基于响应式数据进行动态计算,值会根据其依赖的数据动态计算而来,并且会被缓存,只有相关依赖发生改变时才会重新计算。

1.基本语法

Vue 组件的 computed 选项中,你可以定义计算属性,并提供一个函数来计算属性的值。计算属性会被视为响应式依赖,只有当计算属性内部依赖的数据发生变化时,计算属性才会重新计算。

vue 复制代码
<template>
  <div>
    <p>Radius: {{ radius }}</p>
    <p>Area: {{ area }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      radius: 5
    };
  },
  computed: {
    area() {
      return Math.PI * Math.pow(this.radius, 2);
    }
  }
};
</script>

area 是一个计算属性,它基于 radius 计算圆的面积。每当 radius 变化时,area 会自动重新计算。

1.1计算属性的 getter 和 setter

计算属性还可以包含 getter 和 setter,使其更灵活。

vue 复制代码
<template>
  <div>
    <p>First Name: {{ firstName }}</p>
    <p>Last Name: {{ lastName }}</p>
    <input v-model="fullName">
  </div>
</template>

<script>
export default {
  data() {
    return {
      firstName: 'WW',
      lastName: 'BB'
    };
  },
  computed: {
    fullName: {
      // getter
      get() {
        return this.firstName + ' ' + this.lastName;
      },
      // setter
      set(value) {
        const names = value.split(' ');
        this.firstName = names[0];
        this.lastName = names[names.length - 1];
      }
    }
  }
};
</script>

fullName 计算属性包含了 getter 和 setter。当你读取 fullName 时,它会返回 firstNamelastName 的组合,当你设置 fullName 时,会解析输入的值并更新 firstNamelastName

1.2在父子组件中使用计算属性:

父组件

html 复制代码
<template>
  <div>
    <child-component :first-name="firstName" :last-name="lastName"></child-component>
    <p>{{ fullName }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      firstName: 'WW',
      lastName: 'BB'
    };
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName;
    }
  }
};
</script>

子组件

html 复制代码
<template>
  <div>
    <p>{{ childFullName }}</p>
  </div>
</template>

<script>
export default {
  props: ['firstName', 'lastName'],
  computed: {
    childFullName() {
      return this.firstName + ' ' + this.lastName;
    }
  }
};
</script>

父组件通过 props 将 firstNamelastName 传递给子组件。子组件使用这些 props 来计算自己的 childFullName 计算属性。每当父组件的 firstNamelastName 改变时,子组件的 childFullName 也会随之更新。

2.一些计算属性的使用场景

  1. 数据转换: 用于对已有的数据进行计算,生成新的数据。

  2. 过滤和排序: 在显示列表时,可以使用计算属性对数据进行过滤或排序。

  3. 表单处理: 对表单输入进行实时验证或处理时,计算属性提供了方便的方式。

  4. 复杂逻辑的封装: 当有复杂的逻辑需要基于多个响应式数据进行计算时,使用计算属性可以使代码更清晰。

1. 数据转换:

商店中,每个产品都有一个价格和折扣。现希望计算每个产品的实际价格,即价格减去折扣。

vue 复制代码
<template>
  <div>
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }} - Original Price: {{ product.price }} - Discounted Price: {{ discountedPrice(product) }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { id: 1, name: 'Product A', price: 100, discount: 20 },
        { id: 2, name: 'Product B', price: 150, discount: 30 },
        // ... other products
      ]
    };
  },
  computed: {
    discountedPrices() {
      return this.products.map(product => this.discountedPrice(product));
    }
  },
  methods: {
    discountedPrice(product) {
      return product.price - product.discount;
    }
  }
};
</script>

discountedPrice 是一个计算属性,用于计算每个产品的折扣后价格。discountedPrices 计算属性则用于获取所有产品的折扣后价格。

2. 过滤和排序:

任务列表中,每个任务有一个状态(已完成、进行中、未开始),现希望能够根据状态过滤和排序任务列表。

vue 复制代码
<template>
  <div>
    <select v-model="selectedStatus">
      <option value="all">All</option>
      <option value="completed">Completed</option>
      <option value="inProgress">In Progress</option>
      <option value="notStarted">Not Started</option>
    </select>

    <ul>
      <li v-for="task in filteredTasks" :key="task.id">
        {{ task.name }} - Status: {{ task.status }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tasks: [
        { id: 1, name: 'Task A', status: 'completed' },
        { id: 2, name: 'Task B', status: 'inProgress' },
        // ... other tasks
      ],
      selectedStatus: 'all'
    };
  },
  computed: {
    filteredTasks() {
      if (this.selectedStatus === 'all') {
        return this.tasks;
      } else {
        return this.tasks.filter(task => task.status === this.selectedStatus);
      }
    }
  }
};
</script>

filteredTasks 是一个计算属性,用于根据选定的状态过滤任务列表。用户通过下拉选择框选择任务状态,filteredTasks 计算属性会根据选择的状态动态更新任务列表。

3. 表单处理:

表单中包含两个输入框,分别用于输入用户名和邮箱。在用户输入时进行实时验证,并根据验证结果决定是否显示提交按钮。

vue 复制代码
<template>
  <div>
    <label for="username">Username:</label>
    <input v-model="username" id="username">
    
    <label for="email">Email:</label>
    <input v-model="email" id="email">
    
    <button :disabled="!isFormValid">Submit</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: '',
      email: ''
    };
  },
  computed: {
    isFormValid() {
      return this.username.length > 0 && this.isValidEmail(this.email);
    }
  },
  methods: {
    isValidEmail(email) {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      return emailRegex.test(email);
    }
  }
};
</script>

isFormValid 是一个计算属性,它根据输入的用户名和邮箱实时验证表单的有效性。如果用户名不为空且邮箱格式有效,则启用提交按钮。

4. 复杂逻辑的封装:

一个在线问卷调查,其中有一些问题需要根据先前问题的回答进行逻辑判断。如果用户选择 "有",那么显示下一个问题;如果选择 "无",则跳过下一个问题。

vue 复制代码
<template>
  <div>
    <label>Have you used our product before?</label>
    <select v-model="usedProduct">
      <option value="yes">Yes</option>
      <option value="no">No</option>
    </select>
    
    <div v-if="usedProduct === 'yes'">
      <label>How satisfied are you with our product?</label>
      <select v-model="satisfactionLevel">
        <option value="verySatisfied">Very Satisfied</option>
        <option value="satisfied">Satisfied</option>
        <option value="neutral">Neutral</option>
        <option value="dissatisfied">Dissatisfied</option>
        <option value="veryDissatisfied">Very Dissatisfied</option>
      </select>
    </div>
    
    <p v-if="showFeedbackMessage">Thank you for your feedback!</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      usedProduct: '',
      satisfactionLevel: '',
    };
  },
  computed: {
    showFeedbackMessage() {
      // 复杂的逻辑判断
      return this.usedProduct === 'yes' && this.satisfactionLevel === 'verySatisfied';
    }
  }
};
</script>

showFeedbackMessage 是一个计算属性,它根据用户的回答进行复杂的逻辑判断。只有在用户使用过产品并且非常满意时,才显示感谢反馈的信息。

相关推荐
ZhengEnCi9 分钟前
Q04-Vite禁用CSS代码分割-解决生产环境样式加载顺序混乱问题
前端·vue.js·vite
九酒40 分钟前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
Jackson__1 小时前
做了一段时间的AI coding后,我终于搞清了 CLI 和 MCP 的区别
前端·agent·ai编程
IT_陈寒4 小时前
JavaScript项目实战经验分享
前端·人工智能·后端
用户47949283569155 小时前
6w star,GitHub 趋势第一的 Ponytail,这个agent插件到底在火什么
前端·后端
薛定喵的谔6 小时前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js
张龙6877 小时前
构建生产级 AI Agent:工具调用与记忆架构实战指南
前端
kyriewen7 小时前
2026 年了,还在用 Node.js?Bun 迁移实战:20 分钟搞定,附踩坑记录
前端·javascript·node.js
青山Coding9 小时前
Cesium应用(八):物体运动的实现思路
前端·cesium
用户41659673693559 小时前
Android WebView 加载 file:// 离线页面调试教程
android·前端