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

相关推荐
OpenTiny社区几秒前
TinySearchBox 综合搜索组件重磅更新:实现 Vue 2 和 Vue 3 双版本适配!
前端·javascript·vue.js
GDAL7 分钟前
HTML 实现登录状态记录 深入全面讲解教程
前端·html·登录验证
(づど)8 分钟前
一套齐全的环境设置:nvm\node\nrm\pnpm
前端·笔记
晷龙烬11 分钟前
Vue 3 自定义指令:从“瑞士军刀”到“专属工具” !
前端·javascript·vue.js
MediaTea13 分钟前
思考与练习(第四章 程序组成与输入输出)
java·linux·服务器·前端·javascript
BD_Marathon15 分钟前
【JavaWeb】NPM_简介和相关配置
前端·npm·node.js
咸鱼加辣18 分钟前
【前端框架】react
前端·react.js·前端框架
unicrom_深圳市由你创科技18 分钟前
Vue 3 高效开发技巧总结
前端·javascript·vue.js
HIT_Weston21 分钟前
66、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(十)
前端·ubuntu·gitlab
长空任鸟飞_阿康24 分钟前
LangChain 技术栈全解析:从模型编排到 RAG 实战
前端·python·langchain