Vue中计算属性(computed)和监听属性函数watch的比较

我们知道,在Vue中,可以通过一个计算属性和watch函数来监听某个数据属性的变化,但这两者有一定的差别。在这里就做一下简要探讨。
1、计算属性适用的情形
我们可能会有这样的需求,一个数据属性在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性。
例如在下面这个例子中,如果我们使用监听函数,代码就会变得有点冗余。

<div id="demo">{{ fullName }}</div>

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

fullName属性依赖于firstNamelastName,这里有个缺点就是,无论firstNamelastName其中的任何一个发生改变时,都要调用不同的监听函数来更新fullName属性。但是当我们使用计算属性时,代码就会变得更加简洁。

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

这时,我们只要监听fullName属性就行,至于firstNamelastName属性的任何改变,我们都可以通过fullNamegetter()方法得到最终的fullName值。
另外需要注意的是,计算属性可以同时设置getter()setter()方法。例如:

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

2、监听器watch适当的情形

watch函数适用于,当数据发生变化时,执行异步操作或较大开销操作的情况。来看下面的例子:

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script>
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.getAnswer()
    }
  },
  methods: {
    // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
    // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
    // AJAX 请求直到用户输入完毕才会发出。
      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
          })
      },
      // 这是我们为判定用户停止输入等待的毫秒数
      500
    )
  }
})
</script>

在这个例子中,当question数据属性发生改变时,就会调用getAnswer()方法。该方法被调用后,会执行一个异步请求。最终将得到的结果赋给answer属性。这是计算属性所代替不了的。

猜你喜欢

转载自blog.csdn.net/yangkaige111/article/details/80574858