计算属性
先来看一个小demo:”反转字符串“
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
</head>
<body>
<div id="demo">
{{text}} <br>
<!-- 分割成数组,再反转,再用 , 连接 -->
{{text.split(',').reverse().join(',')}} <br>
<!-- 逻辑过长就会变成臃肿,难以维护,所以遇到复杂的逻辑是,应该使用计算属性-->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//需求:'123,456,789'变成'789,456,123'
var app = new Vue({
el:"#demo",
data:{
text:'123,456,789'
},
})
</script>
</body>
</html>
这个demo{{ }} 中要写很长(好吧其实不算长),如果有更多更复杂的需求,就要在 {{ }} 中写很长的表达式,会很臃肿,难以维护。为了解决这个问题,应该使用计算属性。
<div id="demo">
{{reverseText}}
</div>
<script>
//需求:'123,456,789'变成'789,456,123'
var app = new Vue({
el:"#demo",
data:{
text:'123,456,789'
},
//计算属性
computed:{
//如果计算属性直接跟一个 function 默认的就是 getter 函数
reverseText:function(){
return this.text.split(',').reverse().join(',')
}
}
})
总结:
- 如果表达式过长,或者逻辑过于复杂时,就可以使用计算属性;
- 计算属性中的函数,一定要返回一个值。
方法与计算属性的区别--缓存
同一个demo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>计算属性</title>
</head>
<body>
<div id="demo">
{{text}} <br>
<hr>
计算属性的缓存:<br>
{{now}} <br>
通过method 拿到时间戳(方法一定要加括号):<br>
{{thisTime()}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//需求:'123,456,789'变成'789,456,123'
var app = new Vue({
el:"#demo",
data:{
text:'123,456,789'
},
//计算属性
computed:{
//如果计算属性直接跟一个 function 默认的就是 getter 函数
reverseText:function(){
return this.text.split(',').reverse().join(',')
},
now:function(){
return Date.now()
}
},
//页面中的方法:如果是调用方法,只要页面重新渲染,方法就会重新执行
methods: {
thisTime:function(){
return Date.now()
}
},
})
</script>
</body>
</html>
未修改text 值之前:

当修改 text 值 为app.texrt = 1 值之后,页面渲染值为1。
下面时间戳用计算属性的并未改变,用method写的值发生了改变

结论:
- 计算属性:不管渲染不渲染,只要计算属性依的数据未发生变化,就永远不变
method:页面中的方法:如果是调用方法,只要页面重新渲染,方法就会重新执行,不需要渲染,则不需要执行。 - 没有使用计算属性,在 methods 里定义了一个方法实现了相同的效果,甚至该方法还可以接受 参数,使用起来更灵活。既然使用 methods 就可以实现,那么为什么还需要计算属性呢?原因就是 计算属性是基于它的依赖缓存的。 一个计算属性所依赖的数据发生变化时,它才会重新取值,所以text 只要不改变,计算属性也 就不更新
getter 和 setter
每一个计算属性都包含一个 getter 函数和 setter 函数。
<div id="app">
{{ fullName }} // 3、渲染 fullName
</div>
var app = new Vue({
el: '#app',
data: { // 1、在data中定义 firstName 和 lastName
firstName: 'zahng',
lastName: 'san'
},
computed: { // 2、在计算属性中定义 fullName
fullName: function () {
return this.firstName + this.lastName
}
}
})
//zhang san
上面代码并没有出现 getter 和 setter ,是因为,计算属性默认使用 getter 函数,即使没有明确写出 getter 函数,计算属性也会默认使用它。
改写:
computed: {
fullName: {
get: function () { // 这里就明确写出了 getter 函数
return this.firstName + this.lastName
}
}
}
//上下两段代码完全等价
computed: {
fullName: function () {
return this.firstName + this.lastName
}
}
setter 函数与 getter 函数类似,也是写在计算属性中。而不同之处在于,getter 函数是默认用法,setter 函数不是默认用法。如果你要使用 setter 函数,那么你必须要手动写出 setter 函数。
<div id="aaa">
我的姓名是----{{fullName}}
</div>
var app = new Vue({
el:"#aaa",
data:{
firstname:'zhang',
lastname:'san'
},
computed: {
//计算属性的默认用法是 getter函数
// fullName:function(){
// return this.firstname+' '+this.lastname
// },
//设置全成名字,就要调用set方法
fullName:{
get:function(){
return this.firstname+' '+this.lastname
},
set:function(newValue){
console.log('我是set方法,我被调用了')
//用逗号分隔
var names = newValue.split(',');//分隔为数组
this.firstname = names[0];// 数组第一个值赋值给 firstName
this.lastname = names[1]; // 数组第二个值赋值给 lastName
}
}
},
})
在控制台中改变名字:

总结:
- 每一个计算属性都包含一个 getter 函数和 setter 函数;
- 计算属性会默认使用 getter 函数;
- 也可以提供 setter 函数,当修改计算属性的值时,就会触发 setter 函数,执行一些自定义的操作。
网友评论