浅谈Vue的computed计算属性


Posted in Vue.js onMarch 21, 2022

computed计算属性

1、什么是计算属性

计算属性 本质是方法,只是在使用这些 计算属性 的时候,把他们的名称直接当作 属性 来使用,并不会把 计算属性 当作方法去调用,不需要加小括号 ()调用。

2、为什么要用计算属性

当你需要一个属性是需要经过一些计算的,比如你要一个discounted折扣后的钱属性,现在有price价格,和discount折扣。那么discounted=price*discount。discounted与现有的属性price和discount相关联。

要得出discounted的值,我们可以这样写。

<div>{{price*discount}}</div>

我们不是要 discounted属性吗,这样写貌似不需要添加一个属性,直接用表达计算出折扣后的值就行了。

那么,如果非要得到个discounted呢,我们可能会想到用methods写个方法进行计算

<!--template-->
<div class="price">
        原价:<span v-text="price"></span><br>
        现价: <span v-text="discounted()"></span>
</div>
<!--script-->
  data() {
    return {
      price:100,
      discount:0.8
    }
  },
  methods: {
  discounted(){
      this.price*discount
    }
  },

再看看vue的comunidad计算属性

<!--template-->
<div class="price">
        原价:<span v-text="price"></span><br>
        现价: <span v-text="discounted"></span>
</div>
<!--script-->
computed: {
    discounted(){
      return this.price*this.discount
    }
  },

浅谈Vue的computed计算属性

我们又会想,用表达式price*discount不就可以得出discounted吗,为什么还要费那么大功夫写什么方法,computed。

那么问题就来了,如果我们的discounted是根据你买的金额,按一下规则来:

原价x 折扣
0<x<=50 0.9
50<x<=100 0.85
100<x 0.8

那么我们该如何实现呢?我们先试着直接用表达式看看。

浅谈Vue的computed计算属性

这里报错了,显然不支持多行表达式。如果需要经过一些稍微复杂的计算,我们就必须使用函数了。

浅谈Vue的computed计算属性

但是,还是建议即使是简单的表达式,还是建议写成computed或者computed里

因为我们写程序要有关注分离的思想,比如css就写在< style >里,js就写在< script >里,这样更方便我们阅读,也使代码更加规范。


那么,又有问题来了,这里我们的确得出了想要的值,但我们发现用methods不就行了吗,为啥还要computed呢,这两者有什么区别?

1、methods使用时,一般情况需要加括号,而computed则不需要。

2、methods每次调用时会重新执行函数,而computed在其内部变量不变或其返回值不变的情况下多次调用只会执行一次,后续执行时直接从缓存中获取该computed的结果。

至于为什么computed为什么不像methods一样使用小括号调用,是由于computed本身就是一个属性,其本质是computed内部有两个方法(set和get),computed最终的道德的结果是get方法的返回值,而set方法很少使用到,因此简化写法就是上述正常使用computed的格式。

3、compute、methods和watch三者的区别

  computed methods watch
缓存 没有 没有
异步 不行 不行
触发 模板使用:数据 模板使用:方法 被监控数据发送变动
灵活度 最低 最高
推荐度 最高 其次 最低(依赖关系容易变得复杂)

4、案例:遍历数组对象的时候进行监视

那么我们一般对数组监视,在遍历的时候对当前数组的对象进行监视,我们该怎么做呢。

computed也是也可以传参的,我们要检测哪个对象,把当前对象传入就可以了,这样检测的数据就是动态的。

我直接用昨天玩css写的例子吧。这里只需要关注价格,其他可以忽略,我也懒得改了,哈哈。

<template>
  <div class="container">
    <div
      class="list"
      v-for="item in list"
      :key="item"
    >
      <div class="list-item">
        <img
          :src="item.url"
          alt=""
        >
          <div class="item-select">
            <!-- <div style="width:120px;float:left;">
              <button>喜欢</button>
            </div>
            <div style="width:120px;float:left;">
              <button>不喜欢</button>
            </div> -->
            <svg v-show="!item.like" @click="liked(item)" t="1647706494573" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5953" width="200" height="200"><path d="M935.669676 115.583774C871.255802 51.1699 792.995954 24.681952 709.318118 37.925926c-66.219871 10.23398-133.643739 45.751911-196.853616 102.3398C448.652627 83.677837 381.228759 48.159906 315.008888 37.925926 231.331051 24.681952 153.071204 51.1699 88.65733 115.583774 23.641457 180.599647-7.060483 266.08348 1.367501 355.781305c9.029982 89.095826 55.383892 178.191652 134.245738 257.053498 12.039976 12.039976 55.985891 55.985891 100.533804 100.533804l0 0c53.577895 54.179894 108.359788 108.961787 109.563786 110.165785 0.601999 0.601999 1.203998 0.601999 1.805996 1.203998L511.862503 989.084068l48.761905-48.159906 4.815991-4.213992c9.029982 0 265.481481-267.287478 322.069371-324.477366 78.861846-78.861846 125.215755-167.957672 134.245738-257.053498C1031.387489 266.08348 1000.685549 180.599647 935.669676 115.583774zM147.653215 322.67137c-6.019988 18.059965-9.631981 34.915932-10.835979 47.557907-1.805996 13.845973-13.243974 24.079953-27.089947 24.079953l-1.805996 0c-16.855967 0-30.099941-15.651969-27.089947-32.507937 3.611993-21.069959 9.029982-40.333921 15.049971-57.791887 6.019988-16.253968 25.283951-22.875955 40.333921-14.447972 0 0 0.601999 0 0.601999 0C147.051216 296.183422 151.867207 310.029394 147.653215 322.67137zM364.372792 140.867725c0 13.243974-9.029982 24.681952-22.273956 27.089947-79.463845 13.243974-127.623751 48.159906-158.325691 86.687831-8.427984 10.835979-24.079953 13.845973-36.119929 6.621987 0 0-0.601999 0-0.601999 0-13.845973-8.427984-16.855967-27.691946-7.223986-40.93592 60.199882-78.861846 146.285714-103.543798 192.639624-110.767784 16.855967-2.407995 31.303939 10.23398 31.303939 27.089947L363.770793 140.867725z" p-id="5954" fill="#bfbfbf"></path></svg>
            <svg v-show="item.like" @click="liked(item)" t="1647706494573" class="icon" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5953" width="200" height="200"><path d="M935.669676 115.583774C871.255802 51.1699 792.995954 24.681952 709.318118 37.925926c-66.219871 10.23398-133.643739 45.751911-196.853616 102.3398C448.652627 83.677837 381.228759 48.159906 315.008888 37.925926 231.331051 24.681952 153.071204 51.1699 88.65733 115.583774 23.641457 180.599647-7.060483 266.08348 1.367501 355.781305c9.029982 89.095826 55.383892 178.191652 134.245738 257.053498 12.039976 12.039976 55.985891 55.985891 100.533804 100.533804l0 0c53.577895 54.179894 108.359788 108.961787 109.563786 110.165785 0.601999 0.601999 1.203998 0.601999 1.805996 1.203998L511.862503 989.084068l48.761905-48.159906 4.815991-4.213992c9.029982 0 265.481481-267.287478 322.069371-324.477366 78.861846-78.861846 125.215755-167.957672 134.245738-257.053498C1031.387489 266.08348 1000.685549 180.599647 935.669676 115.583774zM147.653215 322.67137c-6.019988 18.059965-9.631981 34.915932-10.835979 47.557907-1.805996 13.845973-13.243974 24.079953-27.089947 24.079953l-1.805996 0c-16.855967 0-30.099941-15.651969-27.089947-32.507937 3.611993-21.069959 9.029982-40.333921 15.049971-57.791887 6.019988-16.253968 25.283951-22.875955 40.333921-14.447972 0 0 0.601999 0 0.601999 0C147.051216 296.183422 151.867207 310.029394 147.653215 322.67137zM364.372792 140.867725c0 13.243974-9.029982 24.681952-22.273956 27.089947-79.463845 13.243974-127.623751 48.159906-158.325691 86.687831-8.427984 10.835979-24.079953 13.845973-36.119929 6.621987 0 0-0.601999 0-0.601999 0-13.845973-8.427984-16.855967-27.691946-7.223986-40.93592 60.199882-78.861846 146.285714-103.543798 192.639624-110.767784 16.855967-2.407995 31.303939 10.23398 31.303939 27.089947L363.770793 140.867725z" p-id="5954" fill="#d4237a"></path></svg>
          </div>
          <div class="price">
        原价:<span v-text="item.price"></span><br>
        现价: <span v-text="discounted(item)"></span><br>
        (点亮中间的爱心再减5元!)
      </div>
      </div>
  </div>
  </div>
</template>

<script>
export default {
  name: "Child",
  data() {
    return {
      list: [
        {
            price:88.88,
          like: false,
          url:
            "https://tse4-mm.cn.bing.net/th/id/OIP-C.E5Ce0SanbLrLCq6j5IQXVQHaE7?w=268&h=180&c=7&r=0&o=5&dpr=1.12&pid=1.7",
        },
        {
            price:100,
          like: false,
          url:
            "https://img.zcool.cn/community/0146eb57d154f40000018c1b84142e.jpg@1280w_1l_2o_100sh.jpg",
        },
        {
            price:20.56,
          like: false,
          url:
            "https://img.zcool.cn/community/01e89b5ddfb3c7a80120686b029383.jpg@2o.jpg",
        },
        {
          price:100.50,
           like: false,
          url:
            "https://img.zcool.cn/community/0159bc5767a2600000018c1b76f216.jpg@1280w_1l_2o_100sh.jpg",
        },
        {
            price:666.00,
           like: false,
          url:
            "https://img.zcool.cn/community/0132e85e0abc74a8012165180d2178.jpg@1280w_1l_2o_100sh.jpg",
        },
      ],
      price:100,
      discount:0.8
    }
  },
  computed: {
    discounted(){
        return function(item){
          //对价格进行条件计算
          let price = item.price
          if(0<price&&price<=50){
              price = price*0.9
          }else if(50<price&&price<=100){
             price = price*0.85
          }else if(100<price){
             price = price*0.8
          }
          if(item.like){
            price -= 5
          }
          //返回两位小数
          return price.toFixed(2)
        }
    },
  },
  methods: {
    liked(item){
        item.like = !item.like
    }
  },  
};
</script>

<style>
body {
background-image: linear-gradient(to top, #c4c5c7 0%, #dcdddf 52%, #ebebeb 100%);
}
.container {
  margin: 0 auto;
  width: 400px;
  /* border: 1px solid black ; */
}
.list-item {
  margin-top: 40px;
}
p {
  margin: 10px 40%;
}
.list-item img {
  width: 100%;
  height: 300px;
  border-radius: 20px;
  box-shadow: 5px 10px 13px 3px rgba(110, 115, 127, 0.5);
  opacity: 0.8;
  transition: 0.8s;
}
.list-item img:hover {
  opacity: 1;
}
.item-select {
  width: 100%;
  height: 80px;
  position: relative;
}
/* .item-select button {
  color: white;
  font-weight: bold;
  font-family: 幼圆;
  margin-top: 20px;
  width: 100px;
  height: 55px;
  margin-left: 90px;
  background-image: linear-gradient(to top, #a3bded 0%, #6991c7 100%);
  padding: 15px;
  display: inline;
  font-size: 18px;
  text-align: center;
  border-radius: 10px;
  transition: 0.5s;
  white-space: nowrap;
  border: 1px #dee7ec solid;
  opacity: 0.8;
}
button:hover {
  background-image: linear-gradient(to right, #ff758c 0%, #ff7eb3 100%);
  color: white;
  width: 105px;
  height: 60px;
} */
.list-item svg{
  width: 60px;
  height: 60px;
  margin: 20px 170px;
  position:absolute;
  left: 0;
  top: 0;
  transition: 0.3s;
}
.list-item svg:hover{
  width: 65px;
  height: 65px;
  transition: 0.1s;
}
</style>

浅谈Vue的computed计算属性

我们来看看是否监视成功

加个点亮爱心再减5元的功能

添加个liked方法,点击了就将当前对象的like取反

在计算属性中再添加一个条件,当点亮了爱心,也就是like=true,就再减5元

浅谈Vue的computed计算属性

浅谈Vue的computed计算属性

如果点亮爱心,现价可以再减5元,取消点亮,恢复原来的价格,说明监视成功。

来看看效果吧

浅谈Vue的computed计算属性

当取消点亮,价格又会恢复。

浅谈Vue的computed计算属性

Vue.js 相关文章推荐
解决vue elementUI 使用el-select 时 change事件的触发问题
Nov 17 Vue.js
浅析VUE防抖与节流
Nov 24 Vue.js
Vue过滤器,生命周期函数和vue-resource简单介绍
Jan 12 Vue.js
vue实现一个获取按键展示快捷键效果的Input组件
Jan 13 Vue.js
vue 中this.$set 动态绑定数据的案例讲解
Jan 29 Vue.js
Vue实现todo应用的示例
Feb 20 Vue.js
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
vue实现同时设置多个倒计时
May 20 Vue.js
vue使用Google Recaptcha验证的实现示例
Aug 23 Vue.js
vue2的 router在使用过程中遇到的一些问题
Apr 13 Vue.js
vue elementUI表格控制对应列
Apr 13 Vue.js
VUE中的v-if与v-show区别介绍
Mar 13 #Vue.js
Vue.js中v-bind指令的用法介绍
Mar 13 #Vue.js
Vue2.0搭建脚手架
Vue.js中v-for指令的用法介绍
Mar 13 #Vue.js
Vue如何清空对象
Mar 03 #Vue.js
Vue中Object.assign清空数据报错的解决方案
Mar 03 #Vue.js
vue实现移动端div拖动效果
Mar 03 #Vue.js
You might like
php getimagesize 上传图片的长度和宽度检测代码
2010/05/15 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
PHP不用第三变量交换2个变量的值的解决方法
2013/06/02 PHP
PHP 下载文件时自动添加bom头的方法实例
2014/01/10 PHP
PHP命令行执行整合pathinfo模拟定时任务实例
2016/08/12 PHP
jquery 回车事件实现代码
2011/08/23 Javascript
js中call与apply的用法小结
2013/12/28 Javascript
JS获取单击按钮单元格所在行的信息
2014/06/17 Javascript
jquery+css3打造一款ajax分页插件(自写)
2014/06/18 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
javascript合并表格单元格实例代码
2016/01/03 Javascript
JS简单循环遍历json数组的方法
2016/04/22 Javascript
jQuery.uploadify文件上传组件实例讲解
2016/09/23 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
JavaScript实现时间表动态效果
2017/07/15 Javascript
使用vs code开发Nodejs程序的使用方法
2017/09/21 NodeJs
Angular4绑定html内容出现警告的处理方法
2017/11/03 Javascript
vue响应式更新机制及不使用框架实现简单的数据双向绑定问题
2019/06/27 Javascript
Vue.js递归组件实现组织架构树和选人功能
2019/07/04 Javascript
js实现图片跟随鼠标移动效果
2019/10/16 Javascript
跟老齐学Python之编写类之一创建实例
2014/10/11 Python
python基于windows平台锁定键盘输入的方法
2015/03/05 Python
编写简单的Python程序来判断文本的语种
2015/04/07 Python
Python实现PS图像调整黑白效果示例
2018/01/25 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
python将一组数分成每3个一组的实例
2018/11/14 Python
python模糊图片过滤的方法
2018/12/14 Python
Python使用Numpy模块读取文件并绘制图片
2020/05/13 Python
python3实现简单飞机大战
2020/11/29 Python
商务助理岗位职责
2013/11/13 职场文书
婚庆公司的创业计划书
2014/01/22 职场文书
缓刑人员思想汇报500字
2014/09/12 职场文书
2014年销售经理工作总结
2014/12/01 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书
导游词之安徽巢湖
2019/12/26 职场文书
Java内存模型之happens-before概念详解
2021/06/13 Java/Android