Skip to content

计算属性

基本用法

计算属性可以根据已有的响应式数据(源数据),派生出新的响应式数据。而且源数据的变化会导致派生数据的自动变化。语法格式如下:

js
const 响应式数据 = computed(fn)

const 响应式数据 = computed(() => {
  // 必须 return 数据
})

用法示例如下:

js
import { createApp, ref, computed } from 'vue'

const app = createApp({
  setup() {
    // 源数据
    const user = ref({
      firstName: 'longbin',
      lastName: 'liu'
    })

    // 派生出来的数据
    const fullName = computed(() => user.value.firstName + ' ' + user.value.lastName)

    return {
      user,
      fullName
    }
  }
})

app.mount('#app')
html
<div id="app">
  <div v-for="(value, key) in user" :key="key">
    <span>{{key}}:</span>
    <input type="text" v-model="user[key]" />
  </div>

  <hr />
  <p>姓名:{{ fullName }}</p>
</div>

注意

传递给 computed(fn)fn 函数,必须 return 一个值,否则就是无效的计算属性。

水果列表案例

在 JavaScript 中定义源数据和计算属性:

js
setup() {
  // 源数据
  const fruits = ref([
    { id: 1, name: '苹果', price: 2, count: 1 },
    { id: 2, name: '香蕉', price: 1.5, count: 2 },
    { id: 3, name: '橘子', price: 1.8, count: 5 },
    { id: 4, name: '柿子', price: 1, count: 3 }
  ])
  // 计算属性:总数量
  const total = computed(() => fruits.value.reduce((acc, item) => acc + item.count, 0))
  // 计算属性:总价格
  const amount = computed(() => fruits.value.reduce((acc, item) => acc + item.count * item.price, 0))

  return {
    fruits,
    total,
    amount
  }
}

在模板结构中渲染页面:

html
<!-- 循环渲染水果列表的结构 -->
<div v-for="fruit in fruits" :key="fruit.id">
  <span>{{fruit.name}}</span>
  <span> | </span>
  <span>单价:¥{{fruit.price.toFixed(2)}}</span>
  <span> | </span>
  <span>数量:</span>
  <button @click="fruit.count >=2 && fruit.count--">-</button>
  <span>&nbsp;{{fruit.count}}个&nbsp;</span>
  <button @click="fruit.count++">+</button>
</div>

<hr />
<!-- 统计区域 -->
<p>总数量:{{total}}</p>
<p>总价:¥{{amount}}</p>

天不生夫子,万古长如夜