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

相关推荐
GIS程序媛—椰子24 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00130 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端33 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100937 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤43911 小时前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt