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

相关推荐
大得3692 小时前
electron结合vue,直接访问静态文件如何跳转访问路径
javascript·vue.js·electron
水银嘻嘻4 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
小嘟嚷ovo5 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
十一吖i5 小时前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观5 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰5 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米5 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊5 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js
九月TTS6 小时前
TTS-Web-Vue系列:组件逻辑分离与模块化重构
前端·vue.js·重构
我是大头鸟7 小时前
SpringMVC 内容协商处理
前端