This knowledge point often ask, originally I want to put this in a big inside say, but discover write more and more, simply took out alone with one to write, here I sum up my personal understanding of these two knowledge points. The article “Vue Watch Principle” has been referred to, which is highly appreciated.

Listener Watch (one-to-many)

  • role

    In short, listen for changes in data. You can listen for changes in data to perform other operations. This is a one-to-many relationship (where one data affects many data).

  • Commonly used attributes

    • immediate: Specified in the option argumentimmediate: trueThe handler callback is executed as soon as the watch is initialized, rather than waiting for the next data update. Notice in theimmediateOption, you cannot cancel listening on a given callback on the first callbackproperty.
    export default { data() { return { foo: "123", }; }, watch: { foo: { handler(newData, oldData) { console.log("newData:", newData); //123 console.log("oldData:", oldData); //undefined}, immediate: true,// If this property is set to true, the listener will be printed immediately. If it is false, no data will be printed at this time, and the listener will not be printed until foo is changed. ,}}};Copy the code
    • deep: can be set to detect changes in internal valuesdeep: trueWhen listening for changes to an array, you don’t need to do this, because arrays can be detected directly with this.$set.But if you replace one of the attributes of an element of an array object directly, you still adddeep: true.
    export default { data() { return { foo: { name: "yyy", age: "12", }, }; }, watch: { foo: { handler(newData, oldData) { console.log("newData:", newData.age); console.log("oldData:", oldData.age); },}, mounted() {this.foo.age = "321"; }};Copy the code
  • usage

    • Listen for underlying data types

      export default { data() { return { foo: "123", }; }, watch: { foo(newData, oldData) { console.log("newData:", newData); //321 console.log("oldData:", oldData); //123 }, }, mounted() { this.foo = "321"; }};Copy the code
    • Listening to the object

      • Listen for the whole object
        • The result of a substitution is not the same as that of a change. As shown in the figure above, the value before and after the change is the same.
      Export default {data() {return {foo: {name: "XXX ", id: "123", class:" one ",}, bar: {name: "XXX ", id: "123", class: "One ",},}; }, watch: { foo: { handler(newData, oldData) { console.log("newData:", newData.name); //yyy console.log("oldData:", oldData.name); //yyy }, deep: true, }, bar: { handler(newData, oldData) { console.log("newData:", newData.name); //yyy console.log("oldData:", oldData.name); //xxx }, deep: true, }, }, mounted() { this.foo.name = "yyy"; Enclosing the bar = {name: "yyy" id: "321", the class: "one,"}; }};Copy the code
      • Listening for individual properties
      Export default {data() {return {foo: {name: "XXX ", id: "123", class:" one ",},}; }, watch: { 'foo.name'(newData, oldData) { console.log("newData:", newData); //yyy console.log("oldData:", oldData); // XXX},}, mounted() {this.foo.name = "yyy"; setTimeout(() => { this.foo.id = "321"; }, 1000); }};Copy the code
    • Listening to the array

      • Since the old and new data are the same, you can avoid this situation by borrowing deep copies of calculated properties. The same goes for listening objects.
      export default { data() { return { foo: [1, 2, 3, 4, 5], }; }, computed: { bar() { return JSON.parse(JSON.stringify(this.foo)); }, }, watch: { foo(newData, oldData) { console.log("newData:", newData); //[1, 22, 3, 4, 5] console.log("oldData:", oldData); //[1, 22, 3, 4, 5] }, bar(newData, oldData) { console.log("newData:", newData); //[1, 22, 3, 4, 5] console.log("oldData:", oldData); //[1, 2, 3, 4, 5] }, }, mounted() { this.$set(this.foo, 1, 22); }};Copy the code
  • The characteristics of

    Watch allows us to perform asynchronous operations (accessing an API), limit how often we perform that operation, and set intermediate states until we get the final result. These are all things you can’t do with computed properties. The calculated property returns immediately, while the asynchronous operation may not have completed.

    export default { data() { return { foo: "123", }; }, watch: { foo(val) { setTimeout(() => { console.log("foo-data", val); // can trigger}, 1000); }, bar(val) { console.log("bar-data", val); // Cannot trigger},}, computed: {bar() {setTimeout(() => {return this.foo; // Calculate the property immediately return the value and can't do much else. If you don't use setTimeout, you can trigger the watch on the bar above}, 1000); }, }, mounted() { this.foo = "321"; }};Copy the code

Computing properties Computer (many-to-one)

  • role

    In layman’s terms, it is a value or multiple values concatenated or combined to form a value, referring to the transformers complex Hercules. And the data in the computer does not need to be declared again in data.

  • usage

export default { data() { return { foo: "123", bar: "321" }; }, computed: { zoo() { return this.foo + this.bar; },}};}}};Copy the code
  • The characteristics of

    Computed properties are cached based on their reactive dependencies and are evaluated again only when the associated dependencies change. This saves you a lot of performance, whether you use a listener or a function to achieve the same effect, which is not as good as evaluating properties.