17.Vue的计算属性
目录
1.姓名案例插值语法实现
2.姓名案例methods实现
3.姓名案例计算属性实现
4.get什么时候会被调用?
5.set什么时候会被调用?
6.计算属性简写
7.总结
我们这一节将通过一个小案例来讲清楚Vue的计算属性。
案例的实现效果是,有两个输入框,一个输入姓,一个输入名,最后呈现姓-名
当姓或者名改变的时候,最后呈现的姓-名也同步发生改变
但是我们接下来并不会直接用计算属性去实现这个动态效果,而是先用我们之前学过的插值语法和methods的方式分别实现一下,最后再用计算属性去实现,通过这种对比让大家能够明白为什么Vue要设计计算属性的功能以及它的优势在哪里。
1.姓名案例插值语法实现
注意:要实现页面改变数据的这种效果v-bind就已经满足不了需求了,这里就需要使用
v-model:value ,简写形式为v-model
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{firstName + '-' + lastName}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示new Vue({el:'#root',data:{firstName:'张',lastName:'三'}})
</script>
</html>
实现效果:
上面的全名是使用拼接字符串的方式 {{firstName + '-' + lastName}} 写的,其实我们还可以换一种方式写 {{firstName}}-{{lastName}}
那么上面我们就使用插值语法实现了这个需求,这样看都挺好。所以接下来我们再丰富一下这个需求。我们让全名在展示姓的时候只展示前三位。
我们可以像下面这样实现:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示new Vue({el:'#root',data:{firstName:'张',lastName:'三'}})
</script>
</html>
实现效果:
这样虽然实现了效果,但是代码有点小问题,像 {{firstName.slice(0,3)}} 这样的代码是非常不便于观察的,如果我们不仅需要截取3位,还需要反转加全部变为大写,那么这个代码就变得非常长了。这样得话就违背了Vue的简单表达式的原则,我们可以去Vue官网看一下风格指南。
这样的写法并不是错误的写法,只是说Vue并不推荐这样去做,而Vue推荐的方法就是下面这样的计算属性
我们接下来,并不直接使用计算属性。而是通过之前学过的methods的方式去实现这种复杂的业务逻辑。
2.姓名案例methods实现
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName()}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示new Vue({el:'#root',data:{firstName:'张',lastName:'三'},methods:{fullName(){return this.firstName + '-' + this.lastName}}})
</script>
</html>
注意:插值语法中如果写的是函数,则会将函数的返回值插入,插值语法中的函数括号不能省略
实现效果:
实现原理注意点:只要data中的数据发生改变,Vue就会重新解析模板,而在重新解析模板的时候,只要遇到插值语法里面写方法的,这个方法就一定会被重新调用
使用methods去实现这个案例,也可以,但是效率不高。
3.姓名案例计算属性实现
上面我们使用插值语法和methods实现了姓名案例,下面我们就用计算属性来实现一下。
如果我们想理解好计算属性,我们就得先明白什么是属性?对于Vue来说,它认为在data配置项中所写的东西就是属性
红色部分的是属性名,蓝色部分的是属性值
那什么是计算属性呢?计算属性就是,我们拿着我们已有的属性,去加工,计算,然后生成一个全新的属性
在Vue中,属性和计算属性是分开放的,data中放的是属性,而计算属性则放在一个全新的配置项中computed
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_计算属性实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>???</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{fullName:{/*get有什么作用?当有人读取fullName时,get就会被调用且返回值就作为fullName的值这里的get底层调用的其实就是Object.defineProperty中的get方法*/get(){console.log('get被调用')return '123'}}},methods:{}})
</script>
</html>
我们可以看到 当我们访问计算属性的时候,get方法就会被调用。
这里还有一个细节问题需要注意:我们之前说过vm身上有一个_data,而_data中存放的是data中的东西,就目前来说_data中有firstName,lastName,但是绝对没有fullName,因为fullName是属于以后计算出来的东西。而不是当时就写在data中的东西。我们可以去验证一下:
那这个时候就会有人发出疑问,如果_data中没有计算属性,那我们要怎么使用它呢?
其实不要紧,因为fullName是由firstName,lastName经过计算之后得到的,在计算之后会被直接丢到vm身上的。所以我们在使用的时候,就直接使用插值语法读取fullName就行了。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{fullName:{/*get有什么作用?当有人读取fullName时,get就会被调用且返回值就作为fullName的值这里的get底层调用的其实就是Object.defineProperty中的get方法*/get(){console.log('get被调用')return '123'}}},methods:{}})
</script>
</html>
实现效果:
下面我们来真正的实现这个需求。这里就需要注意,在computed配置中,Vue已经帮我们把get方法中的this指向调成了vm。所以我们可以直接使用this的属性值去计算。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName}}</span> <br><br></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{fullName:{/*get有什么作用?当有人读取fullName时,get就会被调用且返回值就作为fullName的值这里的get底层调用的其实就是Object.defineProperty中的get方法*/get(){console.log('get被调用')return this.firstName + '-' + this.lastName}}},methods:{}})
</script>
</html>
4.get什么时候会被调用?
到这里我们就把计算属性写完了,但是我们还得去研究一个问题,就是get什么时候会被调用?
这时候就有人发出疑问,你上面的代码不是已经写了当有人访问fullName的时候,get方法就会被调用吗?为什么还要再问一遍呢?那如果我像下面这样去写呢?
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{fullName:{/*get有什么作用?当有人读取fullName时,get就会被调用且返回值就作为fullName的值这里的get底层调用的其实就是Object.defineProperty中的get方法*/get(){console.log('get被调用')return this.firstName + '-' + this.lastName}}},methods:{}})
</script>
</html>
我们可以看到上面输出了4个 {{fullName}},那是不是就代表get方法会被调用4次呢?我们可以实验一下。
我们可以看到4个 {{fullName}} ,而get方法只被调用了一次。
所以,我们就引申出Vue在计算属性中做的特别好的一件事,就是缓存
它在解读第一个fullName的时候 ,Vue发现有人调用fullName了,于是就去调用get,然后拿到返回值,就作为fullName的值去使用,然后剩下的3个fullName,Vue就不会再去找get要了,直接走了缓存。这个时候反应快的就会想到一个问题,如果是缓存的话,其实也不太好,万一fullName以后改了,那它还是去读缓存的话,不是就有问题了吗,读的还是原来的值。这一点Vue也考虑到了,所以get的调用其实是有两个时机的。下面我们就仔细说说get什么时候调用。
1.初次读取fullName时,get会被调用。
2.所依赖的数据发生变化时,get也会被调用。
那么这个时候计算属性相对于methods的优势就体现出来了,计算属性有缓存而methods没有
5.set什么时候会被调用?
如果我们的计算属性在计算完之后,只是简单的读取,那么只写get方法就足够了,如果我们的计算属性在后期还有可能被修改,则必须有set方法
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span> <br><br>全名:<span>{{fullName}}</span></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{fullName:{/*get有什么作用?当有人读取fullName时,get就会被调用且返回值就作为fullName的值这里的get底层调用的其实就是Object.defineProperty中的get方法*/get(){console.log('get被调用')return this.firstName + '-' + this.lastName},//set什么时候调用,当fullname被修改时set(value){const arr = value.split('-')this.firstName = arr[0]this.lastName = arr[1]}}},methods:{}})
</script>
</html>
实现效果:
6.计算属性简写
刚才我们演示了计算属性的一个完整的情况,有读取,有修改。但是更多的情况,计算属性是不修改的。计算出来,呈现到页面上去看才是更多的情况。而一旦我们确定我们只需要读取不需要修改,我们就可以使用简写形式。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>姓名案例_插值语法实现</title><!--引入Vue--><script type="text/javascript" src="../js/vue.js"></script><style></style>
</head>
<body><!--准备好一个容器--><div id="root">姓:<input type="text" v-model="firstName"> <br><br>名:<input type="text" v-model="lastName"> <br><br>全名:<span>{{fullName}}</span> <br><br></div>
</body><script type="text/javascript">Vue.config.productionTip = false //阻止Vue在启动时生成生产提示const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三'},computed:{//简写形式fullName:function(){console.log('get被调用')return this.firstName + '-' + this.lastName}},methods:{}})
</script>
</html>
而上面的方式还可以继续精简为:
fullName(){console.log('get被调用')return this.firstName + '-' + this.lastName}
7.总结
1.定义:要用的属性不存在,需要通过已有属性计算得来
2.原理:底层借助了Object.defineproperty方法提供的getter和setter
3.get函数什么时候执行?
(1)初次读取时会执行一次
(2)当依赖的数据发生变化时会被再次调用
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高。调试方便
5.备注:
(1)计算属性会出现在vm上,直接读取使用即可
(2)如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。
17.Vue的计算属性相关推荐
- 【Vue】—计算属性缓存VS方法以及侦听器的区别
[Vue]-计算属性缓存VS方法以及侦听器的区别
- 【Vue】—计算属性
[Vue]-计算属性
- Vue的计算属性computed和监听属性watch
Vue的计算属性computed 定义 通过已有属性计算生成一个新的组合属性. 原理 底层借助了Object.defineproperty方法提供的getter和setter来实现. 性质 计算属性的 ...
- vue 的计算属性报错Computed property “disa“ was assigned to but it has no setter.
原因: vue的计算属性不能设置,只能读取 解决:
- Vue的计算属性、侦听属性与过滤器解析
文章目录 知识点 计算属性 计算属性的基本使用 计算属性的 setter 和 getter 侦听属性 计算属性与侦听属性对比 过滤器 过滤器使用方法 过滤器应用场景 综合小练习 知识点 计算属性 计算 ...
- vue computed计算属性
文章目录 前言 一.计算属性介绍 二.使用步骤 1.template中绑定计算属性 2.script中定义计算属性 3.计算属性的配置项 4.计算属性的简写 总结 前言 Vue中的计算属性(comup ...
- vue的计算属性computed
计算属性的应用场景 从已有的数据A中计算等到的新的数据B,使用计算属性 如果一个结果需要依赖data中的数据,但是需要经过一些逻辑处理,才能得到你想要的数据.此时就可以使用计算属性. 定义格式 计算属 ...
- HTML之Vue框架计算属性computed的简单使用实现自动计算总分和平均分
HTML之Vue框架计算属性computed的简单使用实现自动计算总分和平均分 预计效果 代码 结果展示 预计效果 页面输入数学.物理.英语分数,自动计算出总分和平均分,并展示到界面,如下图所示 代码 ...
- vue 02-上计算属性、样式的操作,指令(含自定义,全局和局部)
计算属性: 是一个函数,所依赖的元数据变化时,就会再次执行 典型案例todolistcomputed:{计算属性: function(){return 返回值} 使用: {{计算属性}}}与metho ...
最新文章
- 真是祸从GPT-2口出,和AI聊会天,把别人隐私都给套出来了
- 关于ES性能调优几件必须知道的事
- ITK:计算图像的最小,最大,方差和均值
- Java中expecial,RxJava 学习笔记 (一)
- hiberanate 主键查询慢_mysql查询优化,1万条数据居然要30秒
- Java基本语法(12)--分支结构if-else
- mllib协同过滤 java实现_协同过滤(ALS)算法介绍及Spark MLlib调用实例(Scala/Java/Python)...
- c语言自定义一个函数求商和余数,c – 如何在一个步骤中获得商和余数?
- 携程签约日本爱知县 探索主题游促中日交流
- ubuntu下JNI之HelloWorld相互传String值
- (转)日语时间的表示法
- 【基础教程】关于matlab GUI重命名的问题【739期】
- 交通灯设计(基于Multisim仿真)
- 麻省理工学院公开课:算法导论 观后感 —— 性能是一种货币
- 黑苹果——推荐台式机(翻译自tonymacX86)
- 用VScode绘制函数调用流程图
- Unity最简单的消息中心
- 安卓设备安全相关技术
- 币小秘:币圈五度春秋几度忧愁?解读每位投资者心态
- python的锁机制_python锁机制
热门文章
- python期末考试重点_Python期末复习笔记
- 话说两个很好的PX4博客链接:记录一下咩。
- js Javascript中调用对象内函数.(字符串函数名)
- 如何批量修改多个文件的后缀名!
- 网络offload之TSO、GSO、LRO、GRO
- icpc2018南京站B题 tournament
- ​韩剧影视剪辑30天5710元,短视频大神教你如何快速变现?
- 《数据结构》-第四章 串、数组和广义表(习题)
- 广工anyview数据结构第四章(2021.12)
- Windows 7 新功能 - BitLocker To Go