Advanced usage of watch in Vue.js

Suppose you have the following code:

<div>
      <p>FullName: {{fullName}}</p>
      <p>FirstName: <input type="text" v-model="firstName"></p>
</div>

new Vue({
  el: '#root',
  data: {
    firstName: 'Dawei',
    lastName: 'Lou',
    fullName: ''
  },
  watch: {
    firstName(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    }
  } 
})

The effect of the above code is that when we input firstName, wacthmonitor the new value of each modification change, and then calculate the output fullName.

handler method and immediate property

A feature of watch here is that it will not be executed when it is initially bound, and the monitoring calculation will not be executed until it is firstNamechanged . So what should we do if we want to execute the change when he is initially bound? We need to modify our watch writing. The modified watch code is as follows:

watch: {
  firstName: {
    handler(newName, oldName) {
      this.fullName = newName + ' ' + this.lastName;
    },
    // 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法
    immediate: true
  }
}

Did you notice that handlerwe bound a handlermethod to firstName. The watch method we wrote before is actually written by default handler. Vue.js will handle this logic, and finally compiled it is actually this handler.

On the immediate:trueother hand, if the firstName is declared in falsewacth the same as our previous effect, it will not be executed when binding.

deep attribute

There is also an attribute in watch . The deepdefault value is falsewhether it is deeply monitored. For example, we have an objattribute in data:

<div>
      <p>obj.a: {{obj.a}}</p>
      <p>obj.a: <input type="text" v-model="obj.a"></p>
</div>

new Vue({
  el: '#root',
  data: {
    obj: {
      a: 123
    }
  },
  watch: {
    obj: {
      handler(newName, oldName) {
         console.log('obj.a changed');
      },
      immediate: true
    }
  } 
})

When we enter the value of the data view change in the input box obj.a, we find that it is invalid. Due to the limitations (and deprecations) of modern JavaScript Object.observe, Vue cannot detect the addition or removal of object properties. Since Vue performs a getter/settertransformation , the property must dataexist on the object for Vue to transform it so that it can be responsive.

By default, the handler only listens objfor changes in its reference to this property, and it only listens when we assign a value. For example, we reassign objit in the mounted event hook function :obj

mounted: {
  this.obj = {
    a: '456'
  }
}

This way our handler will execute and print obj.a changed.

Conversely, what if we need to monitor the value objof a property ain it? This deepis where properties come in handy!

watch: {
  obj: {
    handler(newName, oldName) {
      console.log('obj.a changed');
    },
    immediate: true,
    deep: true
  }
} 

deepThe meaning is to observe deeply, the listener will traverse down layer by layer, and add this listener to all the properties of the object, but the performance overhead will be very large, and any modification objof any property in it will trigger the listener. handler in the .

To optimize, we can use string form listener.

watch: {
  'obj.a': {
    handler(newName, oldName) {
      console.log('obj.a changed');
    },
    immediate: true,
    // deep: true
  }
} 

In this way, Vue.js will parse layer by layer until it encounters the attribute a, and then aset the listener function.

log off watch

Why log out watch? Because our components are often destroyed, for example, if we jump a route and jump from one page to another page, then the watch of the original page is actually useless. At this time, we should log out the watch of the original page. Failure to do so may result in built-in overflow. Fortunately, our watch is usually written in the options of the component, and it will be destroyed with the destruction of the component.

const app = new Vue({
  template: '<div id="root">{{text}}</div>',
  data: {
    text: 0
  },
  watch: {
    text(newVal, oldVal){
      console.log(`${newVal} : ${oldVal}`);
    }
  }
});

However, if we write the watch in the following way, then we need to log out manually, which is actually very simple

const unWatch = app.$watch('text', (newVal, oldVal) => {
  console.log(`${newVal} : ${oldVal}`);
})

unWatch(); // 手动注销watch

app.$watchAfter the call, it will return a value, which is the unWatchmethod. If you want to log out of the watch, just call unWatchthe method.

First published on my blog: blog.dunizb.com/Original
link: blog.dunizb.com/2018/04/28/…

Guess you like

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