# 计算属性和监听属性

## 计算属性

使用场景：对于任何复杂逻辑，都应该使用计算属性

计算属性的声明：

只有get 的计算属性使用：

- 在computed属性对象中定义计算属性的方法
- 在页面中使用{{方法名}}来显示计算的结果
- 通过getter/setter实现对属性数据的显示和监视

计算属性由两部分组成，

- get		获取计算属性的值

- set        设置计算属性的值

  get和set都有的计算属性的使用（用的时候可以只用一个）：

  ```
   <div id="app">
          <p>{{firstName}}</p>
          <p>{{lastName}}</p>
          <p>{{fullName}}</p>
          <button @click="changename">change</button>
      </div>
  ```

  ​		

```
var app = new Vue({
            el: '#app',
            data: {
                firstName:"顾",
                lastName:"青衣",
            },
            methods:{
                changename(){
                    this.fullName="顾 念" //中间需要加空格，不然下面的没法拆分
                } 
            },
            computed: {
                fullName: {
                    // getter
                    get: function () {
                        
                        return this.firstName + ' ' + this.lastName
                    },
                    // setter
                    set: function (newValue) {
                        //this.fullName = newValue 这种写法会报错
                        var names = newValue.split(' ')
                        this.firstName = names[0]//对它的依赖进行赋值
                        this.lastName = names[names.length - 1]
                    }
                }
            }
        })
```

注：

计算属性是基于它们的依赖进行缓存的，只有相关的依赖发生改变时才会重新求值。只要相关的依赖未改变，只会返回之前的结果，不会执行函数。

computed依赖监控自己定义的变量，computed不能计算已经在data里面定义过的值，该变量在computed里面定义，然后可以在页面上进行数据绑定

computed比较适合对多个变量或者对象进行处理后返回一个结果值，也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化





## watch

#### 作用

- 主要用于监控vue实例的变化，监控的变量必须在data里面声明才可以
- 可以监控一个变量或者一个对象，但是只能监控整个对象或单个变量，无法监控对象的具体属性

### 使用

- 通过vm对象的$watch()或watch配置来监视指定的属性
- 当属性变化时，回调函数自动调用，在函数内部进行计算
- watch不能双向的绑定值

### 使用场景

- watch一般用于监控路由、input输入框的值特殊处理等等，它比较适合的场景是一个数据影响多个数据

示例：

```
watch:{
    // 监听firstName
    firstName(value){
        console.log(`watch监视到firstName发生改变：${value}`);
        //更新fullName
        this.fullName  = value + '·' + this.lastName
        },
    // 监听lastName
    lastName(value){
        console.log(`watch监视到lastName发生改变：${value}`);
        this.fullName  = this.firstName + '·' + value
        }
    }
```

监听复杂数据类型： （拓展）

> watch:{
>
> ​	监听的数据名:{
>
> ​		handler(val,oldval){
>
> ​			...  发生变化后的回调函数 
>
> ​		}，
>
> ​		deep:true  是否深度监听
>
> ​	}
>
> }

```
var app = new Vue({
            el: '#app',
            data: {
                b: {
                    c: 1
                }
            },
            watch: {
                // newValue(val, oldVal) {
                //     console.log("b.c: " + val, oldVal);
                // }
                b: {
                    handler(val, oldval) {
                        console.log(val, oldval)

                    },
                    deep:true
                }
            },

        })
        app.b.c = 3
```



## 计算属性&监听属性&方法

#### 计算属性vs 方法

不同的是**计算属性是基于它们的响应式依赖进行缓存的**。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 `message` 还没有发生改变，多次访问 `reversedMessage` 计算属性会立即返回之前的计算结果，而不必再次执行函数。 

但是 方法每次调用都会执行



#### 计算属性vs监听属性

- computed 的变量不在data中定义； watch的变量需要在data中定义
- computed支持缓存，只有依赖数据发生改变才会重新计算 ；watch 
- computed 可以监听对象的某个具体属性 ；watch一般用来监听简单数据类型，如果监听对象等复杂数据类型，则无法监听对象具体某个属性  但是watch 也可以进行深度监听，监听整个对象的变化

