Difference between computed and listened attributes

Difference between computed and listened attributes

compute attribute

Design intent

To resolve code clutter caused by complex expression writing in templates

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

This is the result of an inversion of the output message. If written directly on an HTML template, one or two of these complex expressions are acceptable, and many of them can make the code look very messy.

<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 for calculating attributes
    reversedMessage: function () {
      // `this`points to a vm instance
      return this.message.split('').reverse().join('')
    }
  }
})

Characteristic

  1. Ability to modify or integrate one or more data into a new data

  2. Calculated attributes have the ability to monitor changes in the referenced data. When the referenced data changes, the data for calculated attributes also changes (hot update)

Frame listening Property watch

Listeners can also return a new data by manually monitoring changes in the data

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

But for this example, the compute implementation is more concise

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

To achieve the same functionality, watch implementation is often more complex than compute, so why does VUE need the wach option to respond to changes in data?

Design intent

In fact, the purpose of listening for attributes is not to achieve the same function as calculating attributes, but to be able to respond logically when data changes, and watch es are well suited for processing, performing asynchronous or expensive operations when data changes.

For example, in the search bar, bind the contents of an input box in both directions, and when the input changes, send an ajax request to match the requirements of the options.

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>
<!-- because AJAX Libraries and generic tools are already quite ecologically rich. Vue Core code is not duplicated -->
<!-- Provide these features to keep it streamlined. This also gives you the freedom to choose tools you are more familiar with. -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/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: {
    // If `question'changes, this function will run
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500) // Throttle function, only last function executed
  },
  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>

It's also appropriate to handle a logical operation when we need to listen for data beyond a certain limit

Another example is to execute an animation function, listen for opacity changes, and turn off the animation when opacity > 1.

var watchExampleVM = new Vue({
    el: '#watch-example',
    data: {
        opcacity: 0,
        timer
    }
    watch: {
        opacity(val){
    		if(val > 1){
                 window.cancelAnimationFrame(this.timer); // Clear Animation
            }
        }
	},
    methods: {
        animate(){
            this.opacity = this.opacity + 0.05;
            // ......................
            // Perform other animations
            // .....................
            this.timer = window.requestAnimationFrame(this.animate);
        }
        
    }
})

summary

  1. watch is good at scenarios: when you want to do something when one data changes (one data affects changes in multiple data);

  2. Computer is good at scenarios where you want to get a new value (one data is affected by multiple data).

  3. Watch is preferred when you need to perform asynchronous operations when data changes or when the overhead is high (strange errors occur when computer performs asynchronous operations).

Tags: Front-end Vue

Posted on Fri, 12 Nov 2021 17:03:11 -0500 by coldfission