【Vue3】computed 计算属性

computed 基础语法

<template>
  <div>
    <div>
      性:<input v-model="firstName" type="text">
    </div>
    <div>
      名:<input v-model="lastName" type="text">
    </div>
    <div>
      全名:<input v-model="fullName" type="text">
    </div>
    <button @click="changeName">changeName</button>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
let firstName = ref('zhang')
let lastName = ref('san')

// 1.选项式写法 支持一个对象传入getter和setter自定义操作
let fullName = computed<string>({
  get () {
    return firstName.value + '-' + lastName.value
  },
  set(newVal) {
    console.log(newVal.split('-'));
    [firstName.value,lastName.value] = newVal.split('-')
  }
})
const changeName = () => [
  fullName.value = 'xiao-hu'
]


//2.函数式写法,只能支持一个getter函数,不可以修改值
// let fullName = computed(() => firstName.value + '-' + lastName)
// 不可以修改
// const changeName = () => {
//   fullName.value = 'xiao-hu'
// }
</script>

<style lang="scss" scoped></style>

购物车小案例

未使用computed优化

<template>
  <div>
    <input placeholder="搜索" type="text">
  </div>
  <div style="margin-top: 20px">
    <table border width="600" cellpadding="0" cellspacing="0">
      <thead>
        <tr>
          <th>物品名称:</th>
          <th>物品单价:</th>
          <th>物品数量:</th>
          <th>物品总价:</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item,index) in data">
          <td align="center">{{ item.name }}</td>
          <td align="center">{{ item.price }}</td>
          <td align="center"><button @click="item.num>1 ? (item.num--, total()) : null">-</button>{{ item.num }}<button @click="item.num < 99 ? (item.num++, total()) : null">+</button></td>
          <td align="center">{{ item.num * item.price }}</td>
          <td align="center"><button @click="del(index)">del</button></td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="5" align="right">
            总价:{{ $total }}
          </td>
          
        </tr>
      </tfoot>
    </table>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
let $total = ref<number>(0)
interface Data {
  name: string,
  price: number,
  num: number,
}
let data = reactive<Data[]>([
  {
    name: '手机',
    price: 100,
    num: 1
  },
  {
    name: '电脑',
    price: 200,
    num: 2
  },
  {
    name: '笔记本',
    price: 300,
    num: 3
  }
])

const total = () => {
  $total.value = data.reduce((prev:number, next: Data) => {
    return prev + next.num * next.price
  },0)
}
total()
const del = (index:number) => {
  data.splice(index, 1)
  total()

}
</script>

<style lang="scss" scoped></style>

使用computed优化

<template>
  <div>
    <input v-model="keyWord" placeholder="搜索" type="text">
  </div>
  <div style="margin-top: 20px">
    <table border width="600" cellpadding="0" cellspacing="0">
      <thead>
        <tr>
          <th>物品名称:</th>
          <th>物品单价:</th>
          <th>物品数量:</th>
          <th>物品总价:</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(item, index) in searchData">
          <td align="center">{{ item.name }}</td>
          <td align="center">{{ item.price }}</td>
          <td align="center"><button @click="item.num > 1 ? item.num-- : null">-</button>{{ item.num }}<button
              @click="item.num < 99 ? item.num++ : null">+</button></td>
          <td align="center">{{ item.num * item.price }}</td>
          <td align="center"><button @click="del(index)">del</button></td>
        </tr>
      </tbody>
      <tfoot>
        <tr>
          <td colspan="5" align="right">
            总价:{{ total }}
          </td>

        </tr>
      </tfoot>
    </table>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed } from 'vue'
let keyWord = ref<string>('')
interface Data {
  name: string,
  price: number,
  num: number,
}
let data = reactive<Data[]>([
  {
    name: '手机',
    price: 100,
    num: 1
  },
  {
    name: '电脑',
    price: 200,
    num: 2
  },
  {
    name: '笔记本',
    price: 300,
    num: 3
  }
])

// const total = () => {
//   $total.value = data.reduce((prev:number, next: Data) => {
//     return prev + next.num * next.price
//   },0)
// }
const total = computed(() => {
  return data.reduce((prev: number, next: Data) => {
    return prev + next.num * next.price
  }, 0)
})

const searchData = computed(() => {
  return data.filter((item: Data) => {
    return item.name.includes(keyWord.value)
  })
})
// 使用 searchData 搜索后的总价有bug,不会随 searchData 的数据改变(抽空再改啦~~)

const del = (index: number) => {
  data.splice(index, 1)
}
</script>

<style lang="scss" scoped></style>

你可能感兴趣的:(Vue,vue.js,前端,javascript)