乐趣区

关于html5:Vue计算属性computed

明天通过一个购物车的案例简略论述一下 vue 的计算属性,在 vue 中咱们往往须要对数据进行操作后再返回,通常咱们须要写一个相干的操作函数来对这些数据进行操作,不过当初 vue 给这样的数据处理提供了新思路——计算属性。在本例中总价的数据就是利用了该属性。
1. 先做一个简略的购物车界面,进去大略是这个样子:

把代码贴下边

<template>
  <div class="home">
    <Head v-bind:hname="head_name" />
    <div class="car_head">
      <h2> 商品图片 </h2>
      <h2> 商品详情 </h2>
      <h2> 商品单价 </h2>
      <h2> 购买数量 </h2>
      <h2> 单品总价 </h2>
    </div>
    <div class="car" v-for="(item,index) of products" :key="index">
      <div class="p_img">
        ![](item.img_src)
        <p>{{item.p_name}}</p>
      </div>
      <div class="pdetail">
        <p>{{item.p_detail}}</p>
      </div>
      <div class="price">
        <p>¥{{item.p_price}}</p>
      </div>
      <div class="count">
        <div class="num_box">
          <button>-</button>
          <input type="text" v-model="item.p_number">
          <button>+</button>
        </div>
      </div>
      <div class="total">
        <p v-if="item.total === 0"> 未抉择数量 </p>
        <p v-else>¥{{item.total}}</p>
      </div>
    </div>
    <div class="check_box">
      <h2> 总计:</h2>
      <h2>0</h2>
    </div>
  </div>
</template>
<script>
import Head from "@/components/Head"
export default {
  name: 'Home',
  components: {Head},
  data(){
    return{
      head_name:"shopCar",
      products:[
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eb69512d9d6430d865d457ec52eebb51.png?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"小米 11 Ultra",
          p_detail:"1.12''GN2|128°超广角|120X 超长焦|2K 四微曲屏|骁龙 888|IP68 级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh 超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器 ",
          p_price:6499,
          p_number:0,
          total:0
        }
      ]
    }
  }
}
</script>
<style scoped>
  .car{
    width: 1200px;
    height: 228px;
    border: 2px solid #000;
    display: flex;
    justify-content: space-around;
    align-items: center;
    margin: 0 auto;
    margin-top: 6px;
    overflow: hidden;
  }
  .pimg{height: 200px;}
  .car>div{
    width: 220px;
    height: 250px;
    position: relative;
  }
  .car>div>h2{margin-top: 12px;}
  .car_head{
    width: 1200px;
    height: 70px;
    border: 2px solid #000;
    margin: 0 auto;
    display: flex;
    justify-content: space-around;
    align-items: center;
  }
  .check_box{
    width: 1200px;
    height: 70px;
    border: 2px solid #000;
    margin: 0 auto;
    margin-top: 12px;
    position: relative;
  }
  .check_box>h2{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }
  .check_box>h2:first-child{right: 200px;}
  .check_box>h2:last-child{left: 1002px;}
  .pdetail>p{
    font-size: 12px;
    color: #909399;
  }
  .pdetail>p,.price>p,.total>p,.num_box{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }
  .price>p,.total>p,.num_box{
    font-size: 22px;
    left: 50%;
    transform: translateX(-50%);
  }
  .num_box{
    width: 200px;
    height: 36px;
    display: flex;
    justify-content: space-around;
  }
  .num_box>input{
    width: 86px;
    font-size: 22px;
    padding-left: 6px;
    text-align: center;
  }
  .num_box>button{width: 36px;}
</style>

2. 第二步须要在 methods 里增加函数 downPrice(index)和 addPrice(index)对购买数量的两个按钮别离绑定实现加法和减法的性能,这里之所以要传递形参 index 是因为须要依据数组的下标来更改该下标所对应的商品的总价。
代码如下:

  methods:{addPrice(data){this.products[data].p_number += 1;
      this.products[data].total = this.products[data].p_number * this.products[data].p_price;
    },
    downPrice(data){if(this.products[data].p_number > 0){this.products[data].p_number -= 1;
      this.products[data].total = this.products[data].p_number * this.products[data].p_price;
      }
    }
  }

这样咱们就实现了对单个商品的总价的批改性能,(因为 computed 计算属性里的函数不能传参,不能获取该项商品在数组内所对应的下标,因而目前只想到了用这种办法来解决单个商品相加的需要)留神:这里的 input 是与数组每一项的 p_number 双向绑定的,而每一项的总价又在两个加减函数中阐明了等于该项的单价乘以购买数量。

此时箭头处的的单品总价曾经能够随着购买数量的变动而扭转了,然而所有商品的总价还不能变的,这里咱们就用计算属性来计算总价。

3. 先增加几组假数据让购物车看起来更加实在。
数据在此(自取):

      products:[
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/eb69512d9d6430d865d457ec52eebb51.png?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"小米 11 Ultra",
          p_detail:"1.12''GN2|128°超广角|120X 超长焦|2K 四微曲屏|骁龙 888|IP68 级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh 超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器 ",
          p_price:6499,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/34caee2c867bfd8c5e0dc2d8c663e121.jpg?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"小米 11 Pro",
          p_detail:"1.12''GN2|骁龙 888|2K 四微曲屏|IP68 级防水|67W 有线闪充|67W 无线闪充|10W 无线反充|5000mAh 超大电池|LPDDR5|WiFi6(增强版)|哈曼卡顿音频认证|立体声双扬声器 ",
          p_price:4999,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/cb554f30eaa0316b0a736c3d59f21584.png?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"小米 11 青春版",
          p_detail:"轻薄、多彩 / 骁龙 780G / 业余电影相机,前置超级夜景 / AMOLED 柔性直屏 / 超线性立体声双扬声器",
          p_price:2299,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/d47f7ecaa04d92bf2790d4a5d53d9099.png?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"黑鲨 4 Pro",
          p_detail:"骁龙 888 | 增强版 UFS3.1+SSD 磁盘阵列零碎 | 高品质双扬声器,DXOMARK 音频总分第一名 | 120W 极速闪充 +4500mAh 双电竞电池 | 磁能源升降肩键 | 144Hz 三星 E4 屏幕",
          p_price:4499,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/b3553083a4975325eab6470d94465548.jpg?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"小米 10S",
          p_detail:"骁龙 870 | 对称式双扬立体声 | 1 亿像素 8K 电影相机 | 33W 有线快充 | 30W 无线快充 | 10W 反向充电 | 4780mAh 超大电池 | LPDDR5+UFS3.0+Wi-Fi 6 | VC 液冷散热 | 双模 5G",
          p_price:3299,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/68217751d12b1bfd2f9766e458b5e2dd.jpg?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"Redmi K40 Pro",
          p_detail:"骁龙 888 / E4 旗舰直屏 / 120Hz 高刷 / 杜比全景声 / 4520mAh 大电量 / WiFi 6 增强版 / 7.8mm 轻薄机身 / 多功能 NFC / 红外遥控",
          p_price:3699,
          p_number:0,
          total:0
        },
        {
          img_src:"https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/73617424da6ff6b64f9c630387bca874.jpg?thumb=1&w=200&h=200&f=webp&q=90",
          p_name:"Redmi K40",
          p_detail:"骁龙 870 / 新一代 E4 AMOLED 旗舰直屏 / 杜比全景声 / 7.8mm 轻薄机身设计 / 4520mAh 大电量 / 360Hz 三指触控 / 120Hz 高刷新 / X 轴线性马达 / NFC / 红外遥控",
          p_price:2199,
          p_number:0,
          total:0
        }
      ]

此时的渲染成果是这样的:


看起来还是像那么回事的。

4. 接下来就要用到计算属性了,咱们在 computed 里申明一个办法,相似于 watch 里的属性会随时被监听一样,子不过 computed 里的逻辑与 watch 相同,其值是也随着与其相干的值的变动而被动变动,此例中总价应该是每一个单品的总价和,因而咱们能够遍历 products 数组,而后将每一项的总价相加以失去总价。
代码如下:

    all:function(){
      let all = 0;
      for(var i = 0;i < this.products.length;i ++){all += this.products[i].total;
      }
      return all;
    }

这里的 all 会就是该函数中返回的 products 数组中每一项的 total 的和,all 能够间接通过双花括号渲染到视图层里。
因而咱们还须要将 html 代码中的总计局部批改成这样:

    <div class="check_box">
      <h2> 总计:</h2>
      <h2>¥{{all}}</h2>
    </div>

这样一来 all 就会通过解决 (本例中是求每一项 total 的和,其余操作也能够) 后,间接渲染到页面上了。
再来试一试:

此时咱们购买最初三种商品试一试,3299+14796+4398=22493,后果正确。

总之,vue 的 computed 就是将某个参数在 computed 中通过解决后再间接返回,而页面上也能够间接通过双花括号来渲染,极大的进步了开发效率,升高了开发难度。

退出移动版