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 argument
immediate: true
The handler callback is executed as soon as the watch is initialized, rather than waiting for the next data update. Notice in theimmediate
Option, 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 values
deep: true
When 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
- immediate: Specified in the option argument
-
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
- Listen for the whole object
-
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.