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 相关文章推荐
ASP 过滤数组重复数据函数(加强版)
May 31 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
Feb 14 Javascript
javascript-表格排序(降序/反序)实现介绍(附图)
May 30 Javascript
浅析JavaScript动画
Jun 10 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
May 25 Javascript
JS两个数组比较,删除重复值的巧妙方法(推荐)
Jun 03 Javascript
D3.js实现散点图和气泡图的方法详解
Sep 21 Javascript
vue-resource拦截器设置头信息的实例
Oct 27 Javascript
vue2.0 自定义组件的方法(vue组件的封装)
Jun 05 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
Jul 04 Javascript
使用konva和vue-konva库实现拖拽滑块验证功能
Apr 27 Javascript
vue或react项目生产环境去掉console.log的操作
Sep 02 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
PHP如何利用P3P实现跨域
2013/08/24 PHP
firefox firebug中文入门教程 脚本之家新年特别版
2010/01/02 Javascript
基于jQuery的js分页代码
2010/06/10 Javascript
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
jquery根据name属性查找的小例子
2013/11/21 Javascript
js使用递归解析xml
2014/12/12 Javascript
深入分析Cookie的安全性问题
2015/03/01 Javascript
js实现的下拉框二级联动效果
2016/04/30 Javascript
ES6所改良的javascript“缺陷”问题
2016/08/23 Javascript
Bootstrap导航简单实现代码
2017/03/06 Javascript
jquery拖动改变div大小
2017/07/04 jQuery
微信小程序 五星评分的实现实例
2017/08/04 Javascript
JS设计模式之命令模式概念与用法分析
2018/02/06 Javascript
jQuery幻灯片插件owlcarousel参数说明中文文档
2018/02/27 jQuery
详解redux异步操作实践
2018/08/15 Javascript
vue-cli构建vue项目的步骤详解
2019/01/27 Javascript
详解vue项目打包步骤
2019/03/29 Javascript
JS实现音量控制拖动
2020/01/15 Javascript
Vue实现简易计算器
2020/02/25 Javascript
[04:03]DOTA2肉山黑名单梦之声 风暴之灵中文配音鉴赏
2013/07/03 DOTA
python实现的简单猜数字游戏
2015/04/04 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
python中adb有什么功能
2020/06/07 Python
Python调用REST API接口的几种方式汇总
2020/10/19 Python
python 实现Harris角点检测算法
2020/12/11 Python
英国PC组件和在线电脑商店:SCAN
2019/04/18 全球购物
犹他州最古老的体育用品公司:Al’s
2020/12/18 全球购物
中科软测试工程师面试题
2012/06/16 面试题
启动一个线程是用run()还是start()
2016/12/25 面试题
房地产融资计划书
2014/01/10 职场文书
职工趣味运动会方案
2014/02/10 职场文书
秋季校运动会广播稿
2014/02/23 职场文书
党员学习中共十八大思想报告
2014/09/12 职场文书
2015年社区居委会工作总结
2015/05/18 职场文书
Python+uiautomator2实现自动刷抖音视频功能
2021/04/29 Python
Python 实现定积分与二重定积分的操作
2021/05/26 Python