It has been a year since the release of Vue3.0. It seems that the release of Vue3.0 will take some time. In the development plan, the following statement: Vue3.0 will transform the observer mode based on Proxy. Vue3.0 does not resort to ES5’s Object.defineProperty, but uses the latest Proxy syntax to implement Vue’s most fundamental reactive principle.
The following mainly describes the implementation of observer mechanism exploration from Object.defineProperty to proxy. At present, there are a lot of articles on the principle of deep responsiveness, many of which are well written. This article does not do deep source parsing in VUE. Just a shallow exploration and hand-write a simple Object. DefineProperty to implement the observer mechanism, and hand-write a simple Proxy to implement the observer mechanism, of course, the final release will be subject to the author. There are mainly the following points of knowledge to take you into
Object.defineproperty implements observer mechanism
2. Disadvantages of Object.defineProperty
3. Use proxy to realize simple observer mechanism
4, summarize
Object.defineproperty implements observer mechanism
Object defineProperty() method in ES5 and some basic knowledge, then write a simple response, and finally combine the vUE source code brief analysis.
1.1 Object-defineProperty Basic knowledge
Define Object.defineProperty() on developer.mozilla.org
Object.defineProperty()
Method directly defines a new property on an object, or modifies an existing property of an object and returns the object
Object. DefineProperty (obj, prop, Descriptor) Parameter descriptions: 1. Obj Specifies the Object on which attributes are to be definedCopy the code
Here we focus on the third parameter in the syntax, the property descriptor: Descriptor
There are two main types of property descriptors that currently exist in objects: data descriptors and access descriptors. A data descriptor is a property with a value that may or may not be writable. Access descriptors are properties described by getter-setter function pairs. The descriptor must be one of these two forms; You can’t be both. The optional key, enumerable, value, WritableGet, and set parameters are configurable
1.2 Creating Objects
Usually we create objects to learn step by step about the use of key values in the object.defineProperty () method and property descriptors
[1] Normally we create an object as follows, then the console prints them we can see
let vm = {
name: 'the nuggets'
}
console.log(vm)Copy the code
[2] Next we create an Object via Object.defineProperty and set the property “name” for the Object to define or modify.
// let vm = {
// name: 'the nuggets'
// }
let vm = Object.defineProperty({},"name", {get() {
console.log("Get");
return "Nuggets"
},
set(newValue) {
console.log("Set");
console.log("New value:" + newValue);
}
})
console.log(vm)Copy the code
In fact, both methods of creating an Object, the Object created through Object.defineProperty, we can see that with the two access descriptor key value methods like get and set, the Object becomes controllable to be observed, that is, hijacked. When we change or acquire properties of this object, we can control it.
Now we change vm.name = “juejin”, which we can see from the console
// let vm = {
// name: 'the nuggets'
// }
let vm = Object.defineProperty({},"name", {get() {
console.log("Get");
return "Nuggets"
},
set(newValue) {
console.log("Set");
console.log("New value:" + newValue);
}
})
vm.name = "juejin";
//console.log(vm)Copy the code
1.3 Implement observer mechanism, responsive object
let vm = {
id:"juejin",
name:"Nuggets"};
let keys = Object.keys(vm);
keys.forEach(key=>{
let value = vm[key];
Object.defineProperty(vm, key,{
get() {
console.log("Get");
return value
},
set(newValue){
console.log("Set");
if(newValue! =value){ value = newValue; } } }) }) vm.id ="test";
console.log(vm)Copy the code
Each attribute is given get and set, so that the change of each attribute in the object will be monitored, that is, the responsive observer mechanism is realized.
1.4 VUE source code in the response principle brief analysis
The above example we try, array object detection is not work, then in vue array is how to implement the principle of reactive, we can see the vue source directory SRC/core/observer/index. The js, actually he is a judgment on the object, if is an array of objects, ObserveArray (), and you’ll notice there’s an arrayMethods, The ‘push’, ‘pop’, ‘shift’, ‘unshift’, ‘splice’, ‘sort’, and ‘reverse’ methods have been overwritten to not only do the same things, but also publish messages to subscribers. All other objects go to the walk () method.
1.5 Render data to the page
When we detect an object update, how do we synchronize the update to the page?
1. First, we need to find the node in scope (vue, which will have el:”#app”) where all page content will be rendered
2. Then go through any place on the node where the object is used, known as the interpolation of text with Mustache syntax, such as {{vm}}
3. Bind view updates
Object. DefineProperty
2.1 Cannot listen for the addition and deletion of non-existing attributes of objects
Vue only performs data hijacking on all the original attributes of the object. That is to say, Vue does not allow dynamic addition or deletion of the existing attributes of the object. It does not do data hijacking, so it cannot realize responsiveness.
For example,
<template>
<div>
<h1>{{ vm }}</h1>
<button @click="addAttribute"</button> < button@click ="delAttribute"</button> </div> </template> <script>export default {
data() {
return {
vm:{
id:"juejin",
name:"Nuggets"
}
}
},
methods: {
addAttribute() {
this.vm.use = "codercao"
console.log(this.vm)
},
delAttribute() {
for(let k in this.vm) {
if(k=='id'){
delete this.vm[k]
}
}
console.log(this.vm)
}
},
}
</script>Copy the code
Click On New Properties, and you’ll see that the VM printed by the console has the use property added, and the page has not changed in response
Click Delete Properties, and you’ll see that the VM printed by the console has removed the ID property, and the page has not changed in response
2.2 Array variation
Array objects can’t be controlled by properties or indexes such as length or index to be responsive, We can also see from 1.4 that the vue source code only rewrites the array ‘push’, ‘pop’, ‘shift’, ‘unshift’, ‘splice’, ‘sort’, ‘reverse’, but there is no way to implement the index control array responsivity.
2.3 Solutions to the above. Use the vue.set (object, propertyName, value) method
Modify the new attribute method in 2.1 above, and you will find that the page is responsive. The vue.set method describes the move
addAttribute() {
//this.vm.use = "codercao"
this.$set(this.vm,'use'.'codercao')
console.log(this.vm)
},Copy the code
Three, the use of proxy to achieve a simple observer mechanism
3.1 Proxy Basic knowledge
ProxyObject to define the custom behavior of basic operations (such as property lookup, assignment, enumeration, function call, etc.)
grammarletp = new Proxy(target, handler); Parameter Description Target Proxy wrapped target object (which can be any type of object, including a native array, a function, or even another Proxy) Handler An object whose properties are functions that define the behavior of the Proxy when an operation is performedCopy the code
let vm = {
id:"juejin",
name:"Nuggets"
}
let newVm = new Proxy(vm,{
get(target,key){
console.log("Get");
return target[key];
},
set(target,key,newValue){
console.log("Set");
if(target[key]! ==newValue) target[key] = newValue; } }) newVm.use ="codercao"
console.log(newVm)Copy the code
You’ll find that proxies also provide a simple observer mechanism, but if you dig deeper, you can also implement bidirectional binding.
Fourth, the end
This is the end of this article. As for how the author will use proxy to write the observer mechanism, we can see it when vue3.0 is released. This article mainly introduces you to explore the implementation of Object. This Object. DefineProperty defect and handling method, and then introduce proxy, is a relatively preliminary attempt, Vue has developed to now a few years, in fact, most people are already proficient in its application, pay attention to the source code and practice of Vue function principle, maybe there will be some improvement for each front-end people.