Vue学习笔记(五):计算属性
1 模板与方法的不足?
有两个输入款,一个输入姓(firstname),一个输入名(secondname),fullname由转换为大写字母的姓、横线、转换为大写字母的名拼接组成,当姓或者名修改时,页面上实时显示修改后fullname。使用模板语法,可以很容易实现:
<div id="app"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{firstName.toUpperCase()}}-{{lastName.toUpperCase()}}span> div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' } }) script>
这种方法原理简单,在实现上很好理解,但是过于繁琐,如果在页面中多次用到fullname,那次用到时,都需要进行转化、拼接。所以,进一步的,何以使用函数的方法进行实现:
<div id="app"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名:<span>{{ fullname() }}span> div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' }, methods:{ fullname(){ return this.firstName.toUpperCase() + '-' + this.lastName.toUpperCase() } } }) script>
使用函数的方法实现后,代码看起来更加优雅,但是如果在页面中多出使用到fullname,那么,还是需要多次调用fullname()方法,每次调用fullname()方法时,都会进行拼接等运算,大大降低页面渲染效率。针对这些问题,于是就有了“计算属性”的出现。
2 计算属性?
在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以,所以,我认为可以将计算属性看做是Vue对象中定义的一个特殊的属性。当在页面中,如果多处使用到同一个计算属性,计算属性中的所有运算过程也只需要执行一次,因为计算属性有将结果保存到缓存中的特性,再次使用时,可以从缓存中进行读取。当然,如果计算属性计算过程中设计相关变量发生变化,使用计算属性时,会再次重新执行运算过程,不同担心读取缓存而导致读取的结果“过期”。
计算属性在Vue实例中的“computed”中进行定义, 调用时不需要再属性名后面添加“()”。当在页面中使用“fullname”时,Vue会自动调用fullname中的get方法:
<div id="app"> 姓:<input type="text" v-model="firstName"> <br/><br/> 名:<input type="text" v-model="lastName"> <br/><br/> 全名计算第1次:<span>{{ fullname }}span><br/><br/> 全名计算第2次:<span>{{ fullname }}span><br/><br/> 全名计算第3次:<span>{{ fullname }}span> div> <script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' }, computed:{ // 此处定义计算属性 fullname:{ get:function(){ console.log('读取fullname ……') return this.firstName.toUpperCase() + '-' + this.lastName.toUpperCase() } }, } }) script>
在上述实例代码中,计算属性在3出被调用,但是,真实运算的过程只执行了一次,所以,在控制台只会有一条输出结果,如下所示:|
在计算属性中,除了“getter”也可以添加“setter”方法,“setter”的作用是为计算属性赋值的同时,完成一些其他操作,例如上述例子中,在“setter”中,我们为fullname赋值,同时,根据赋值结果,修改“firstname”和“second”的值:
<script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 var vm = new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' }, computed:{ // 此处定义计算属性 fullname:{ get:function(){ console.log('读取fullname ……') return this.firstName.toUpperCase() + '-' + this.lastName.toUpperCase() }, set(value){ console.log('修改fullname',value) const arr = value.split('-') this.firstName = arr[0] this.lastName = arr[1] } }, } }) script>
在绝大多数计算属性中,setter是不需要的,可以不用写上。通过上述例子我们知道,计算属性是通过getter和setter来实现取值和赋值,getter是必须有的。当只考虑读取(getter)不考虑赋值(setter)时,getter可以进一步简写,上述例子可以简写为:
<script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 var vm = new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' }, computed:{ // 此处定义计算属性 fullname: function(){ console.log('读取fullname ……') return this.firstName.toUpperCase() + '-' + this.lastName.toUpperCase() } } }) script>
甚至还可以进一步将计算属性直接简写为一个函数的形式,不过,必须注意,简写为函数不代表就真是函数,在其他地方使用到时,还是直接使用,不需要想函数一样加上“()”调用:
<script type="text/javascript"> Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。 var vm = new Vue({ el:'#app', data:{ firstName:'zhang', lastName:'san' }, computed:{ // 此处定义计算属性 fullname(){ console.log('读取fullname ……') return this.firstName.toUpperCase() + '-' + this.lastName.toUpperCase() } } }) script>