> For the complete documentation index, see [llms.txt](https://zpliu.gitbook.io/booknote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zpliu.gitbook.io/booknote/vue/05-ji-suan-shu-xing-he-zhen-ting-qi.md).

# 计算属性和侦听器

## 1.模板内表达式

```javascript
//在模板表达式中可以添加一些表达式，但是当表达式放入很多逻辑的时候会变得更加难以维护
<div>
{{message.split('').reverse().join()}}    
</div>
```

对于这种情况我们应该将数据属性使用getter函数， 调用回调函数对原始数据进行操作，将结果返回给computed属性

## 2.使用计算属性的缓存和方法的性能比较

```javascript
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
//现在使用计算属性
<p>{{reverseMessage}}</p>
```

**相比之下计算属性依赖于原始数据，只有原始数据发生改变是计算数学才会发生改变；而调用方法去得到原始数据似乎消耗更大**

## 3.计算属性与侦听属性的性能比较

```javascript
.computed:{
    fullname:function(){
        return this.firstName+this.lastName;
    }
}
.watch:{
    firstName:function(val){
        //监听firstName属性，发生改变时将新的值传递给回调函数
        this.fullName=val+this.lastName
    },
    lastName:function(val){
        //监听firstName属性，发生改变时将新的值传递给回调函数
        this.fullName=this.firstName+val
    }
}
```

* 计算属性还可以根据得到的值，设置其他属性的值

  ```javascript
  .computed:{
      fullName:{
          get:function(){
             return this.firstName+this.lastName; 
          },
          set:function(val){
              var names = newValue.split(' ')
                this.firstName = names[0]
                this.lastName = names[names.length - 1]
          }
      }
  }
  ```

## 4.使用侦听器的场合

​ 通过watch更适合对异步或者数据变化开销比较大的操作

​ **文档中主要使用了一个防抖函数使得函数内部代码的执行往后推迟一段时间**

```javascript
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // 如果 `question` 发生改变，这个函数就会运行
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
    // 在这个例子中，我们希望限制访问 yesno.wtf/api 的频率
    // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
    // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识，
    // 请参考：https://lodash.com/docs#debounce
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})
</script>
```

* created表明在vue实例对象生成后执行代码，此时数据还没有绑定到DOM上，一般在created中调用ajax
* \_.debounce 调用函数n秒之后，才会执行该动作；如果在n秒内又调用了该函数，则重新计算执行时间
