浅谈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 tags 创建缓存导航的过程实现
Dec 03 Vue.js
Vue与React的区别和优势对比
Dec 18 Vue.js
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
vue watch监控对象的简单方法示例
Jan 07 Vue.js
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
vue实现验证用户名是否可用
Jan 20 Vue.js
Vue CLI中模式与环境变量的深入详解
May 30 Vue.js
关于Vue中的options选项
Mar 22 Vue.js
Vue3中toRef与toRefs的区别
Mar 24 Vue.js
vue中data里面的数据相互使用方式
Jun 05 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 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
MySQL数据源表结构图示
2008/06/05 PHP
php中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
php mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
PHP随手笔记整理之PHP脚本和JAVA连接mysql数据库
2015/11/25 PHP
PHP简单预防sql注入的方法
2016/09/27 PHP
浏览器无法运行JAVA脚本的解决方法
2008/01/09 Javascript
Javascript客户端将指定区域导出到Word、Excel的代码
2008/10/22 Javascript
用innerhtml提高页面打开速度的方法
2013/08/02 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
js 动态修改css文件的方法
2014/08/05 Javascript
jquery拖动层效果插件用法实例分析(附demo源码)
2016/04/28 Javascript
js实现文字无缝向上滚动
2017/02/16 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
用js屏蔽被http劫持的浮动广告实现方法
2017/08/10 Javascript
vue项目中的webpack-dev-sever配置方法
2017/12/14 Javascript
node.js实现微信开发之获取用户授权
2019/03/18 Javascript
webpack4 SplitChunks实现代码分隔详解
2019/05/23 Javascript
JavaScript使用prototype属性实现继承操作示例
2020/05/22 Javascript
Python中的浮点数原理与运算分析
2017/10/12 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
Python一行代码实现快速排序的方法
2019/04/30 Python
django的auth认证,authenticate和装饰器功能详解
2019/07/25 Python
Python高级特性 切片 迭代解析
2019/08/23 Python
Python如何读取文件中图片格式
2020/01/13 Python
Django实现图片上传功能步骤解析
2020/04/22 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
基于OpenCV的网络实时视频流传输的实现
2020/11/15 Python
阻止移动设备(手机、pad)浏览器双击放大网页的方法
2014/06/03 HTML / CSS
可能这些是你想要的H5软键盘兼容方案(小结)
2019/04/23 HTML / CSS
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
瑞士灯具购物网站:Lampenwelt.ch
2018/07/08 全球购物
Currentbody德国站:健康与美容技术专家
2020/04/05 全球购物
制冷与空调专业毕业生推荐信
2014/07/07 职场文书
超级详细实用的pycharm常用快捷键
2021/05/12 Python
Java数组详细介绍及相关工具类
2022/04/14 Java/Android