Vue计算属性——computed

孙据
• 阅读 1324

今天通过一个购物车的案例简单阐述一下vue的计算属性,在vue中我们往往需要对数据进行操作后再返回,通常我们需要写一个相关的操作函数来对这些数据进行操作,不过现在vue给这样的数据处理提供了新思路——计算属性。在本例中总价的数据就是利用了该属性。
1.先做一个简单的购物车界面,出来大概是这个样子:
Vue计算属性——computed
把代码贴下边

<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双向绑定的,而每一项的总价又在两个加减函数中说明了等于该项的单价乘以购买数量。
Vue计算属性——computed
此时箭头处的的单品总价已经可以随着购买数量的变化而改变了,但是所有商品的总价还不能变的,这里我们就用计算属性来计算总价。

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
        }
      ]

此时的渲染效果是这样的:
Vue计算属性——computed
Vue计算属性——computed
看起来还是像那么回事的。

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的和,其他操作也可以)后,直接渲染到页面上了。
再来试一试:
Vue计算属性——computed
此时我们购买最后三种商品试一试,3299+14796+4398=22493,结果正确。

总之,vue的computed就是将某个参数在computed中经过处理后再直接返回,而页面上也可以直接通过双花括号来渲染,极大的提高了开发效率,降低了开发难度。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(