# 第三章 计算属性
>[success] 可在此处查看运行文档中的代码示例结果:[https://github.com/jianyaoo/Vue](https://github.com/jianyaoo/Vue)
[toc]
## 基础
**<span style="padding-top:15px;display:inline-block">背景</span >**
插值语法可以在模板中使用表达式进行计算,目的是用于简单计算。但是当逻辑比较复杂且比较多时,会使模板太过繁重而难以维护。
**<span style="padding-top:15px;display:inline-block;">用处</span>**
计算属性用于处理复杂逻辑的表达式。
**<span style="padding-top:15px;display:inline-block;">如何使用</span>**
计算属性在模板中与普通属性用法一致。但是写在实例的computed属性内,一般是一个函数,执行结果返回一个确切的值。
**<span style="padding-top:15px;display:inline-block;">基础示例</span>**
```JavaScript
<body>
<div id="app">
<p>{{getNewData}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
msg:"hello,vue",
},
computed:{
getNewData:function () {
return this.msg.split(",").reverse().join("&");
},
},
})
</script>
</body>
```
## 计算属性的setter方法
计算属性默认只有getter函数,所以一般来说:计算属性是一个可以返回确切值得函数(即默认的getter函数)。但是也可以手动设置setter函数触发一些事件。
**<span style="padding-top:15px;display:inline-block;">触发方法</span>**
手动修改计算属性的值得时候就会触发计算属性的setter方式。**修改计算属性的值得方法和修改普通属性的值的方法一致,例如上例中修改计算属性的值则为:vm.getNewData = "hello,world"**
**<span style="padding-top:15px;display:inline-block;">代码实例</span>**
```
<body>
<div id="app">
<p>{{updataNewData}}</p>
<button @click="handleClick">设置msg值</button>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
msg:"hello,vue",
},
computed:{
updataNewData:{
get:function () {
console.log("计算属性");
return this.msg.split(",").reverse().join("!!!");
},
set:function (value) {
this.msg = value;
},
}
},
methods:{
handleClick:function () {
this.updataNewData = "seen,flag";
}
}
})
</script>
</body>
```
**<span style="padding-top:15px;display:inline-block;">执行说明</span>**
* 在模板中首先渲染的为msg的vue!!!hello
* 点击按钮,修改计算属性的值,触发计算属性的setter函数
* setter函数修改了计算属性的依赖属性值
* 计算属性重新计算,重新渲染最后模板渲染为flag!!!seen
## 计算属性的缓存
>[info] 计算属性的本质是一个可以返回确切值的函数,所以能够通过计算属性实现的代码使用methods属性定义的函数能够达到相同的目的。
**<span style="padding-top:15px;display:inline-block;">计算属性的缓存机制</span>**
计算属性时基于依赖值进行缓存的。当依赖值不发生变化的时候,计算属性就不会重新请求,可以直接获取到计算属性的值。只有依赖值发生改变的时候,计算属性才会重新执行计算。
**<span style="padding-top:15px;display:inline-block;">计算属性 vs 函数</span>**
什么时候使用计算属性,性能开销比较大。比如大量数组且要做大量计算时,又有其他计算属性依赖该属性时。
什么时候时候函数,需要传参且不需要缓存
**<span style="padding-top:15px;display:inline-block;">计算属性与函数的代码实例</span>**
```
<body>
<div id="app">
<p>{{updataNewData}}</p>
<p>{{getMessage()}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
msg:"hello,vue",
},
computed:{
updataNewData:function(){
return this.msg.split(",").reverse().join("!!!");
},
},
methods:{
getMessage:function () {
return this.msg.split(",").reverse().join("!!!")
}
}
})
</script>
</body>
```
## 计算属性与侦听属性
**<span style="padding-top:15px;display:inline-block;">什么是侦听属性</span>**
侦听属性是写在实例的watch属性中的函数,侦听某个值,当该值发生变化时触发监听函数
**<span style="padding-top:15px;display:inline-block;">代码实例</span>**
```
<body>
<div id="app">
<p>{{getMessage()}}</p>
<p>{{watchMsg}}</p>
<button @click="handleClick">设置msg值</button>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
msg:"hello,vue",
watchMsg:""
},
computed:{
getNewData:function () {
return this.msg.split(",").reverse().join("!!!");
},
},
watch:{
msg:function (val) {
this.watchMsg = this.msg.split(",").reverse().join("!");
}
},
methods:{
handleClick:function () {
this.msg= "seen,flag";
}
}
})
</script>
</body>
```
**<span style="padding-top:15px;display:inline-block;">监听和计算属性的区别</span>**
* 监听属性有一个对应的监听字段,用来记录值变化后产生的影响。即案例中的watchMsg
* 计算属性是当依赖值发生变化时,修改函数的返回值。
* 侦听属性是侦听值发生变化时触发侦听事件,直接修改侦听属性的值
## 侦听器
> 当数据变化时需要异步或者开销比较大时,可以使用自定义的侦听器。