Vue计算属性的使用


Posted in Javascript onAugust 04, 2017

我们都知道在Vue构造函数的参数对象中有一个【data】属性,该属性值是一个对象,该对象是对数据的代理,是一个键值对并且时刻与页面表现是一致的,但是这里面只能是简单的键值对,不能拥有业务逻辑,并且由于【data】中的属性属于同一个生命周期,所以如果我们需要某一个属性是依赖于另外一个属性时,在【data】中是做不到的,于是Vue为我们提供了【计算属性】

一、计算属性

1.1 概述

计算属性归根结底也是属性,它也是跟表现层是时刻同步的,虽然我们可以在插值中对数据进行各种处理,但是插值中的表达式处理毕竟只能用于简单的运算,不能拥有太多的业务逻辑。

<body>
  <div id="app">
    <h1>{{name.toUpperCase()}}</h1>
    <!-- <h1>BLUE</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      name: 'blue'
    }
  })
</script>

上面代码是我们熟悉的在插值中使用表达式,但是这里面我们不能写入业务代码。

1.2 计算属性语法

在构造函数的参数对象中有一个【computed】属性,该属性就是用于定义计算属性的,该对象中的【键】也就是我们的计算属性,与【data】不同的是,计算属性的键值是一个【拥有返回值的函数】,该函数中可以访问到【data】中的所有属性。

<body>
  <div id="app">
    <h1>{{rs}}</h1>
    <!-- <h1>BLUE LOVE PINK</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      hs: 'BLUE',
      wf: "PINK"
    },
    computed: {
      rs:function(){
        return `${this.hs} LOVE ${this.wf}`
      }
    }
  })
</script>

上面代码属性【rs】是定义的一个计算属性,该属性值是通过【data】中的两个属性值计算得到,返回一个拼接的字符串(这儿使用了ES6的【模板字符串】)并且当【data】中的相关值变化之后,【rs】属性都会进行重新计算。

可能刚开始对计算属性会有些疑惑,比如上面的例子我把代码写成下面这样子也是可以的

<body>
  <div id="app">
    <h1>{{hs}} LOVE {{wf}}</h1>
    <!-- <h1>BLUE LOVE PINK</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      hs: 'BLUE',
      wf: "PINK"
    }
  })
</script>

上面的代码运行效果和我们使用计算属性的效果是一样的,但是这样的写法只适用于简单的处理,【计算属性可以处理更复杂的业务逻辑】,比如我们根据【data】中的一个属性值进行数据请求用于构建一个属性,我们就必须使用计算属性了。

【注意!!】计算属性虽然是一个方法,但是在Vue内部会被翻译成一个属性,我们可以使用实例【vm.rs】访问到数据的。

1.3 计算属性和过滤器的比较

如果用于对【data】中【单个】属性的【简单】处理,推荐使用过滤器,但是如果一个值使用了【data】中至少2个值或者对一个值进行复杂处理,那么就推荐使用计算属性了。

<body>
  <div id="app">
    <h1>{{hs | lover}}</h1>
    <!-- <h1>BLUE LOVE PINK</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      hs: 'BLUE',
    },
    filters: {
      lover(value){
        return `${value} LOVE PINK`
      }
    }
  })
</script>

上面代码就使用了一个【data】属性值做简单的处理,所以使用过滤器,而且也发现了过滤字符串“LOVE PINK”是不可变的。

1.4 计算属性和Methods的比较

计算属性就是为了定属性的时候处理复杂的业务逻辑,而且在插值中我们可以使用表达式,那么我们是否可以通过使用在插值中调用一个有返回值的函数呢?它和计算属性又有什么区别呢?

<body>
  <div id="app">
    <h1>{{rs}}</h1>
    <!-- <h1>EULB</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      name: 'BLUE',
    },
    computed: {
      rs: function () {
        return [...this.name].reverse().join('');
      }
    }
  })
</script>

上面代码将数据进行反向处理(使用了【ES6数组字符串扩展】 ),当我们改变name的值的时候,计算属性【rs】会跟着改变。下面我们将它改成一个方法结合插值表达式进行处理,看看区别。

<body>
  <div id="app">
    <h1>{{ rs() }}</h1>
    <!-- <h1>EULB</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      name: 'BLUE',
    },
    methods: {
      rs() {
        return [...this.name].reverse().join('');
      }
    }
  })
</script>

上面代码将计算属性改成了一个方法结合插值表达式,发现效果和计算属性没差别,改变name的值的时候页面也刷新了。那是不是这两者就真的没区别呢,答案当然是否定的,如果没有区别干嘛还有计算属性的存在。

【计算属性是基于依赖进行缓存的】,只有计算属性的依赖发生改变时才会重新求值,也就是说如果依赖没有发生改变,那么计算属性会立刻返回之前的计算结果,假如我们有一个性能开销比较大的的计算属性 A ,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。

1.5 计算属性和Watch的比较

我们发现计算属性会监听依赖,如果依赖发生变化则会从新计算属性,那么【监听器】也有这么一个功能,那么我们应该在什么时候使用【计算属性】,什么时候使用【监听器】呢?

<body>
  <div id="app">
    <h1>{{fullName}}</h1>
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      firstName: 'Jack',
      lastName: 'Blue',
      fullName: 'Jack Blue'
    },
    watch: {
      firstName: function (val) {
        this.fullName = val + ' ' + this.lastName
      },
      lastName: function (val) {
        this.fullName = this.firstName + ' ' + val
      }
    }
  })
</script>

上面代码中我们监听firstName和lastName用于构建fullName,效果很好,当firstName和lastName任意一个值改变的时候fullName都会随之改变。下面我们看一下计算属性的写法

<body>
  <div id="app">
    <h1>{{fullName}}</h1>
    <!-- <h1>Jack Blue</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      firstName: 'Jack',
      lastName: 'Blue',
    },
    computed: {
      fullName() {
        return this.firstName + ' ' + this.lastName
      }
    }
  })
</script>

上面代码使用计算属性的方式进行了改造,fullName 依赖 firstName和 lastName 两个属性,当这两个属性任意一个发生变化,fullname都会重新进行计算。但是计算属性是不是简洁了很多呢!

【总结!!】当一个属性需要依赖多个【data】中的属性时,建议使用计算属性,如果我们不是对属性进行操作,只是单纯的依据【data】中的某个值变化后做一些【非属性操作】时或者是在数据变化响应时,【执行异步操作或开销较大的操作】(比如:将变化后的值存入数据库,而不是改变其他属性)就使用Watch。

1.6 计算属性的setter

上面我们是使用的计算属性都是用于对计算属性的取值,计算属性默认页只给了【getter】,但是在需要的时候我们可以人为的添加【setter】

<body>
  <div id="app">
    <h1>{{fullName}}</h1>
    <!-- <h1>Jack Blue</h1> -->
  </div>
</body>

<script>
  let vm = new Vue({
    el: "#app",
    data: {
      firstName: 'Jack',
      lastName: 'Blue',
    },
    computed: {
      fullName: {
        //getter
        get() {
          return this.firstName + ' ' + this.lastName
        },
        //setter
        set(newValue) {
          var names = newValue.split(' ')
          this.firstName = names[0]
          this.lastName = names[names.length - 1]
        }
      }
    }
  })
</script>

上面代码定义了计算属性的一个setter,注意当需要定义setter的时候语法上面是有区别的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 组件之旅(三):用 Ant 构建组件
Oct 28 Javascript
纯JS实现的批量图片预览加载功能
Aug 14 Javascript
javascript工具库代码
Mar 29 Javascript
javascript 获取图片尺寸及放大图片
Sep 04 Javascript
node.js中的console.warn方法使用说明
Dec 09 Javascript
jQuery插件jPaginate实现无刷新分页
May 04 Javascript
jquery实现简单的全选和反选功能
Jan 02 Javascript
jquery鼠标悬停导航下划线滑出效果
Sep 29 jQuery
JavaScript基于面向对象实现的猜拳游戏
Jan 03 Javascript
微信小程序位置授权处理方法
Jun 13 Javascript
vue 全局环境切换问题
Oct 27 Javascript
JS监听Esc 键触发事键
Apr 14 Javascript
JS+Ajax实现百度智能搜索框
Aug 04 #Javascript
vue插件vue-resource的使用笔记(小结)
Aug 04 #Javascript
分享Bootstrap简单表格、表单、登录页面
Aug 04 #Javascript
vue-cli项目如何使用vue-resource获取本地的json数据(模拟服务端返回数据)
Aug 04 #Javascript
使用jQuery实现鼠标点击左右按钮滑动切换
Aug 04 #jQuery
vue修改vue项目运行端口号的方法
Aug 04 #Javascript
详解Angular2表单-模板驱动的表单(Template-Driven Forms)
Aug 04 #Javascript
You might like
解决163/sohu/sina不能够收到PHP MAIL函数发出邮件的问题
2009/03/13 PHP
用php实现让页面只能被百度gogole蜘蛛访问的方法
2009/12/29 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
2013/06/06 PHP
apache和PHP如何整合在一起
2015/10/12 PHP
thinkPHP自定义类实现方法详解
2016/11/30 PHP
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
2009/11/14 Javascript
一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)
2010/06/02 Javascript
深入分析js中的constructor和prototype
2012/04/07 Javascript
JavaScript中使用arguments获得函数传参个数实例
2014/08/27 Javascript
基于JavaScript创建动态Dom
2015/12/08 Javascript
javascript中new关键字详解
2015/12/14 Javascript
微信小程序 教程之WXSS
2016/10/18 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
RequireJs的使用详解
2017/02/19 Javascript
微信小程序手势操作之单触摸点与多触摸点
2017/03/10 Javascript
vue项目关闭eslint校验
2018/03/21 Javascript
Layer组件多个iframe弹出层打开与关闭及参数传递的方法
2019/09/25 Javascript
基于JavaScript实现控制下拉列表
2020/05/08 Javascript
[01:24:16]2018DOTA2亚洲邀请赛 4.6 全明星赛
2018/04/10 DOTA
Python实战之制作天气查询软件
2019/05/14 Python
基于python进行抽样分布描述及实践详解
2019/09/02 Python
Python数学形态学实例分析
2019/09/06 Python
解决Pytorch 加载训练好的模型 遇到的error问题
2020/01/10 Python
关于初始种子自动选取的区域生长实例(python+opencv)
2020/01/16 Python
使用pytorch实现论文中的unet网络
2020/06/24 Python
在keras中对单一输入图像进行预测并返回预测结果操作
2020/07/09 Python
Amara美国站:英国高端家居礼品网站,世界各地的奢侈家具品牌
2017/07/26 全球购物
超市促销实习自我鉴定
2013/09/23 职场文书
药学专业个人的自我评价
2013/12/31 职场文书
回门宴父母答谢词
2014/01/26 职场文书
岗位廉政承诺书
2014/03/27 职场文书
家具公司总经理岗位职责
2014/07/08 职场文书
学校2014重阳节活动策划方案
2014/09/16 职场文书
丽江古城导游词
2015/02/03 职场文书
雾霾停课通知
2015/04/24 职场文书
钢铁是怎样炼成的读书笔记
2015/06/29 职场文书