In-depth understanding of Vue's computed properties

  Computed properties are a very evil thing. As long as a property in data is referenced in its function, when this property changes, the function seems to be able to sniff the change and automatically re-execute it.

  The above code will continuously print out the value of b. If you want a to change depending on the x in data, just make sure that there is this.x in the a function. If the attribute in data does not appear in the function, no matter how the attribute in data changes, the function corresponding to a will not be executed once.

      How does Vue know which data property the computed property refers to in the function? How does this function know that the data attribute has changed, and it only cares about the attribute it references internally, and nothing else?

1. The description of the computed property in the official documentation is:

  Expressions inside templates are very convenient, but they are designed for simple operations. Putting too much logic in a template can make the template heavy and difficult to maintain. So, for any complex logic, you should use computed properties.

  You can bind computed properties in templates just like normal properties. Vue knows about vm.reversedMessagedependencies vm.message, so vm.messagewhen changes are made, vm.reversedMessagethe bindings for all dependencies are updated as well. And best of all, we've created this dependency declaratively: computed property getters have no side effects, which makes it easier to test and understand.

1、computed VS methods

  You may have noticed that we can achieve the same effect by calling methods in expressions, and we can define the same function as a method instead of a computed property. The end result of both ways is indeed exactly the same. The difference, however, is that computed properties are cached based on their dependencies . A computed property is only re-evaluated when its associated dependencies change . This means messagethat multiple accesses to reversedMessagea computed property will immediately return the result of the previous computation without having to execute the function again, as long as it has not changed. ( caching effect ) This also means that the following computed properties will no longer be updated, since they Date.now()are not reactive dependencies:

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

  By contrast, calling the method will always execute the function again whenever a re-render is triggered.

  Why do we need caching? Suppose we have a computationally expensive property A that needs to traverse a huge array and do a lot of calculations. Then we may have other computed properties that depend on A. Without caching, we would inevitably execute A's getter multiple times! If you don't want caching, use methods instead.

2、computed VS watch

  Vue provides a more general way to observe and respond to data changes on Vue instances: listening for properties . When you have some data that needs to change with other data, it's easy to abuse watch- especially if you've used AngularJS before. However, it is often better to use computed properties instead of imperative watchcallbacks . Consider this example:

<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
    }
  }
})

  上面代码是命令式且重复的。将它与计算属性的版本进行比较,会发现计算属性好多了。

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

  虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,watch这个方式是最有用的。

3、计算属性默认只有 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]
    }
  }
}

  现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325018772&siteId=291194637