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 】Props – Colloqual version

Today we’re going to look at how props works in plain English

Sure, everyone has used props as a way to pass from father to son, but have you ever wondered how it works?

I want to look at the reaction principle first, which is helpful for understanding props

Response principle


Let me start with three questions

How does the parent component pass value to the props of the child component

How to read props for subcomponents

3, how to update the props of the parent component data

Today we begin our presentation with three questions

If you know these three questions, you should understand how props works





The setting

We now have one such root component, A, and its child component, Testb

The root component A passes parentName to the props of the child component testb

The root component A is also the parent of component testb

<div class="a" >
    <testb :child-name="parentName" ></testb>
</div>
Copy the code
new Vue({    
    el:".a".name:"A".components: {testb: {props: {childName:""
            },            
        template: '

The parent component passed the props value {{childName}}

'
, } }, data(){ return { parentName:"I'm the parent component"}}})Copy the code

Follow the example above to begin our problem analysis

How does the parent component pass a value to the props of the child component

This is going to be a lot, but this is the most important part of the props, so you have to understand

1. Set the props pass value

Testb is a child component that receives a props (child-name)

The root component A then binds its parentName to the child component’s property child-name

2. Props before the father passes on his son

The parent component’s template is parsed into a template rendering function

(function() {    

    with(this) {return _c('div', {staticClass:"a"},[

            _c('testb', {attrs: {"child-name":parentName}})

        ],1)}})Copy the code

This code needs to be explained

Although I do not want to involve the source code, but this code is very helpful to our understanding, and not difficult, so I decided to put up

_c(‘testb’) renders the testb subcomponent

2. Because with binds the variable access scope of the code in braces

This is an anonymous self-executing function that will be executed later

Simplify the above function and test it with an example

function test(){    

    with(this) {console.log(parentName) }

}
test.call({parentName:"Test name"})
Copy the code

As you can see, I’m binding test to an object scope, with to this, and then reading parentName gets the parentName from the object passed in

So with that in mind, let’s look at the next step

3. Props starts assigning

After that, the template function is executed, binding the parent component to scope

So all variables inside the rendering function are fetched from the parent component object

Once the parent scope is bound, the parentName is naturally fetched from the parent component, like this

{ attrs: { child-name: parentVm.parentName } }

Copy the code

The function executes, with the internal _c(‘testb’) executed first, and attrs as assigned

Attrs after the parent component is assigned looks like this

{ attrs: { child-name: "I'm the parent component"}}Copy the code

The parent component formally passes parentName to the props child-name of the child component using props

4. Save props for subcomponents
_c('testb', {attrs: {"child-name":parentName}})
Copy the code

Attrs contains ordinary attributes and props, so you need to filter out props and save it

5. Subcomponents set up responsive props

The props is saved in the _props of the instance and copied to the instance one by one, and each property is set to reactive

As you can see, each instance is going to have an _props, but it’s also going to put properties directly on the instance.

I’m not gonna lie to you okay





How does the component read props

From the above question, we know that the child saves the data passed in by the parent

The data for prop is copied to the VM object (instance this of the child component) one by one

However, for each property, the get and set functions are set, and access and assignment transitions are performed

Here is a piece of code I simplified the source code, to understand

Object.defineProperty(vm, key, {    

    get() {        

        return this._props[key]

    },    

    set(val) {        

        this._props[key] = val

    }
});
Copy the code

I’m going to take one of the properties of props childName, okay

Object.defineProperty(childVm, childName, {    

    get() {        

        return this._props.childName

    },    

    set(val) {        

        this._props.childName = val

    }
});
Copy the code
Access to the transfer

ChildName = vm._props. ChildName = vm._props

Assignment through

ChildName = 5, vm._props. ChildName = 5

But if you just assign props here, you’re not affecting the parent component’s data. Well, the two things are completely unrelated

Just like when your dad gives you money, how do you use it, it doesn’t affect him

conclusion

-Dan: Yeah, sure. Props is definitely breaking the law and cheating consumers





How does the parent component props update its data

As anyone who read my last article knows

There will be a dedicated Watcher for each instance

What this Watcher does

1. Use the instance to update the view itself

2, used for storing dependent properties, and then notifying instance updates when the properties change

I explained the responsivity principle in the last article, so if you don’t understand it here, check it out

[Vue principle] Responsive principle – vernacular version

ParentName is the parent component’s data, which is then passed to the props of the child component

ParentName collects the watcher of the parent component

In the parent component rendering function

(function() {    

    with(this) {return _c('div', {staticClass:"a"},[

            _c('testb', {attrs: {"child-name":parentName}})

        ],1)}})Copy the code
TIP

Because Vue caches the component’s rendering functions, updates can be made faster by reading from the cache without reparsing

The render function then executes, opening a new props assignment, which brings us back to the first question, if you don’t remember





conclusion

The value of the parent component data is not related to the props of the child component. Changing the props does not affect the parent component data, but if an object is passed in, modifying the object will affect the parent component because the data is passed in as is

2. Props is also responsive, similar in nature to data

3, the props access switch, and assign the switch to the vm._props property