computed计算属性和watch侦听属性

computed: 依赖于响应式依赖数据,当响应式依赖发生变化的时候,自身才会改变,若响应式依赖没有发生改变,那么后续返回的值都是之前的,不会进行重新计算。定义的计算属性名称可以像 data 中声明的变量一样直接使用。在一个计算属性的函数中可以侦听多个响应式依赖。

watch: 侦听自身响应式依赖数据的变化,当自身发生改变后触发定义的函数内容。可以在侦听函数内执行异步开销较大的操作以及设置中间状态,但是一个侦听函数只侦听一个响应式依赖,并且不会产生新的变量名称。

computed

模板内使用表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

<div id="example">
  {
    
    {
    
     message.split('').reverse().join('') }}
</div>

在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中的多处包含此翻转字符串时,就会更加难以处理。

所以为了维持代码的整洁性以及可读性,对于任何复杂逻辑,你都应当使用计算属性。

而 reversedMessage 是依赖于 响应式依赖 message的,当 message 发生变化时, reversedMessage 也会随之改变。

<div id="example">
  <p>Original message: "{
    
    { message }}"</p>
  <p>Computed reversed message: "{
    
    { reversedMessage }}"</p>
</div>

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

同样的我们可以通过在表达式中调用方法来达到一样的效果:

<p>Reversed message: "{
    
    { reversedMessage() }}"</p>

methods: {
    
    
  reversedMessage: function () {
    
    
    return this.message.split('').reverse().join('')
  }
}

不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {
    
    
  now: function () {
    
    
    return Date.now()
  }
}

watch

当需要在数据变化时执行异步开销较大的操作时,使用 watch 方式是最有用的。

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{
   
   { answer }}</p>
</div>
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
        })
    }
  }
})

在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

猜你喜欢

转载自blog.csdn.net/qq_45488467/article/details/127979968