Writing an article is not easy, click a like brother focus on Vue source code sharing, the article is divided into vernacular version and source version, vernacular version to help understand the working principle, source version to help understand internal details, let us study together based on Vue version [2.5.17]

If you think the layout is ugly, please click the link below or pull to the following public account can also be

Vue principle agent Data – source version

Writing this article, I just want to record my exploration of a question about Data, very brief

How is the data of data directly accessible through instances?

The first thought, maybe, is to go through and copy one by one?

But it’s not. There’s a word here called proxy.

How do you represent them? Listen to me slowly, grasp one question at a time, follow me slowly explore






Initialize data

The example uses initData to initialize data as follows

function initData(vm) {     

    var data = vm.$options.data;    

    var keys = Object.keys(data);   

    var i = keys.length;

    data = vm._data =

    ( typeof data === 'function' ?

        data.call(vm) : data ) || {};   



    while (i--) {   

        var key = keys[i];  

        if{proxy(vm,"_data", key); }}}Copy the code

First, get the data. If data is a function, get the return value. Otherwise, get the set object data

Second, save the data

As you can see in the source code, data is saved to the instance

vm._data = 
    typeof data === 'function' ? 
        data.call(vm) : data
Copy the code

Initialize the data in order to retrieve the data and store it on the instance as the proxy headquarters






2, the agent bloom

Next, to enlarge the recruit, to the [data agent] focus, see the source code at the end of the above

The data object is iterated over and the proxy is set if the property name does not begin with [_ or $]

Why avoid those two leading attributes?

The Vue website also explains this

The rest of the properties are going to be set to proxy, so let’s look at the part about setting the proxy

proxy(vm,"_data",key)
Copy the code

What is a proxy? Don’t worry, wait until I put the source code

function proxy(target, sourceKey, key) {    

    Object.defineProperty(target, key, {

        get() {            

            return this[sourceKey][key]

        },

        set(val) {            

            this[sourceKey][key] = val; }}); }Copy the code

Do you understand? DefineProperty is used to set the get and set functions to the proxy

And maybe it’s a little bit unintuitive, but let me make it a little bit clearer by taking a property

So it’s going to look like this

Here’s simplified code for setting responsiveness to the _data property

There are four such functions

1. Name can be accessed directly from vm

React generates a layer more than this.state. XXX to access state. Vue creates a layer more than this.state. XXX to access state

2. Ensure data unification

If, as we thought in the beginning, we assign values one by one, then when the data changes, we have to maintain two copies at the same time, which is hell. But the processing of methods is copied directly to the instance

3. Dependency collection is not affected

When vm.name is accessed and agent vm.name is triggered, vm._data.name is accessed and headquarters Vm. _data.name is triggered, which is used to rely on collection. It doesn’t matter at all

4, does not affect the dependency update

Assign vm.name to trigger agent vm.name set, which will be directly assigned to headquarters vm._data.name, which will trigger vm._data.name set, which will be used for dependency updates. It doesn’t matter at all