We all know that the value of the transmission between the vue parent and child components is used to use props and emit, but in the past, we all needed the value of the grandparents and grandchildren to be intermediaries. When the ancestors have values to be passed to the grandchildren, the children need to pass the value to the grandchildren as intermediaries. When the grandchildren want to change the value of the grandchildren, they need to emit the child first, and then the children emit the parent's method to change the value of the grandchildren. If the multi-level components are nested, then the transmission between the grandchildren will become very cumbersome. In order to solve this requirement, the vue2.4 version has produced three attributes: $attrs, $listeners, and inheritAttrs.
vm.$attrs
Official API
vm.$attrs
2.4.0 new, type: { [key: string]: string }, read only
detailed:
Contains attribute bindings (except class and style) in the parent scope that are not recognized (and obtained) as props (except class and style). When a component does not declare any props, it contains all parent scope bindings (except class and style) and can be passed into internal components via v-bind="$attrs" - useful when creating high-level components.
Introduction to use
From the official introduction, we can conclude that $attrs is applied to the parent-child pass-through scenario. The child component can access all attributes passed by the parent component through $attrs. However, it should be noted that if the attributes passed by the parent component are declared in the child component props, then the attribute will not appear in the $attrs object.
The above example
<template> <div> <p>I'm the parent component</p> <test name="tom" :age="12" : class="child" style="color: red" /> </div> </template> <script> export default { components: { test: { template: ` <div> <p>I'm a child component</p> <test2 v-bind="$attrs" s1="sss" s2="sss" /> </div>`, props: ["name"], created() { (this.$attrs); // {age: 12, id: 12345} }, components: { test2: { template: `<p>I'm a grandson component</p>`, props: ["age", "s1"], created() { (this.$attrs); // {s2: "sss", id: 12345} } } } } } }; </script>
First, you can see that the parent component passes five attributes: name, age, id, class, and style to the child component. The name attribute is declared in the child component props. Because the class and style attributes will be excluded from $attrs, the $attrs printed in the child component finally outputs {age: 12, id: 12345}
Then, the child component passes its $attrs object to the grandson component, and at the same time passes two attributes s1 and s2 to the grandson component. The grandson component declares two attributes age and s1 in its own attribute props, and finally prints out {s2: "sss", id: 12345} It can be seen that the $attrs of the grandson component merges the attributes passed from the parent component and the child component, and excludes the attributes declared in props.
At this point, the introduction of $attrs ends. The following is to introduce inheritAttrs
inheritAttrs
Official API
inheritAttrs
2.4.0 new, type: boolean, default value: true
detailed:
By default, attribute bindings that are not considered props in parent scope will "fall back" and apply as normal HTML attributes to the root element of the child component. When writing a component that wraps one target element or another, this may not always be consistent with the expected behavior. By setting inheritAttrs to false, these default behaviors will be removed. These features can be enabled through the (also added in 2.4) instance attribute $attrs, and can be explicitly bound to non-root elements through v-bind.
Note: This option does not affect class and style binding.
Introduction to use
The official explanation looks very frightening, but the default is to add attributes on the $attrs object that are not declared in the child component props to the root html tag of the child component.
The above example
<template> <div> <p>I'm the parent component</p> <test name="tom" age="12" class="child" style="color: red" /> </div> </template> <script> export default { components: { test: { template: `<p>I'm a child component</p>`, props: ["name"], inheritAttrs: true, // Default is true created() { (this.$attrs); // {age: "12"} } } } }; </script>
You can see that the parent component passes the name and age attributes to the child component. The name attribute is declared in the child component props. After the above code is parsed by the browser
<div> <p data-v-469af010>I'm the parent component</p> <p data-v-469af010 age="12" class="child" style="color: red;">I'm a child component</p> </div>
You can see that the age attribute not declared in the child component props is written into the tag. If you do not want this, you can set inheritAttrs in the child component to false. The parsed result is as follows
<div> <p data-v-469af010>I'm the parent component</p> <p data-v-469af010 class="child" style="color: red;">I'm a child component</p> </div>
You can see that the attributes in the tag disappear, and you can see that the class and style attributes are not affected.
At this point the introduction of inheritAttrs ends
This is the article about the specific use of Vue2.4.0 $attrs and inheritAttrs. This is all about this article. For more related contents of Vue2.4.0 $attrs and inheritAttrs, please search for my previous articles or continue to browse the related articles below. I hope everyone will support me in the future!