background
Now let’s talk about a situation where the parent communicates with the grandchild. How many solutions do we have?
- We use VueX for data management, but if there is less shared state among multiple components in a project, the project is small, and there is less global state, then using VueX for this functionality is not the full power of VueX.
- B is used as A transfer station. When A component needs to transmit information to C component, B accepts the information of A component and then uses attributes to transmit it to C component. This is A solution, but if there are too many nested components, it will lead to cumbersome code and difficult code maintenance. If A state change in C needs to be passed to A, use the event system to pass it up one level.
- A custom Vue central data bus is suitable for cross-level messaging of components, but the disadvantage is low maintenance and low readability of code in multi-party cooperation
I. Document description
(1) $props: The props object received by the current component. The Vue instance proxies access to properties of its props object.
$attrs: contains feature bindings (except class and style) that are not recognized (and retrieved) as prop in the parent scope.
$listeners include V-ON event listeners in the parent scope (without.native modifiers). Internal components can be passed on via V-on =”listeners”
Two, specific use
1. Parent component
<template>
<div>
<div>Father components</div>
<Child
:foo="foo"
:zoo="zoo"
@handle="handleFun"
>
</Child>
</div>
</template>
<script>
import Child from './Child.vue'
export default {
components: { Child },
data() {
return {
foo: 'foo'.zoo: 'zoo'}},methods: {
// Pass events
handleFun(value) {
this.zoo = value
console.log('Sun Tzu component hit event, I received it')}}}</script>
Copy the code
2. Child Component (child.vue)
The middle tier, which acts as a pass-through between the parent and the grandchild, adds v-bind=”$attrs” to the grandchild so that the grandchild can receive data.
$attrs is data passed in from the parent and not received by the child, such as zoo
<template>
<div class='child-view'>
<p>The son component --{{$props. Foo}} has the same content as {{foo}}</p>
<GrandChild v-bind="$attrs" v-on="$listeners"></GrandChild>
</div>
</template>
<script>
import GrandChild from './GrandChild.vue'
export default {
// Inherits the contents of all parent components
inheritAttrs: true.components: { GrandChild },
props: ['foo'].data() {
return{}}}</script>
Copy the code
3. Grandchild.vue
Be sure to use props in the grandson component to receive data from the parent component
<template>
<div class='grand-child-view'>
<p>The grandson components</p>
<p>Data passed to grandchild component: {{zoo}}</p>
<button @click="testFun">Click me to trigger the event</button>
</div>
</template>
<script>
export default {
// Do not want to inherit all of the parent component's content, and do not display attributes on the component root element DOM
inheritAttrs: false.// This component needs to receive data from the parent component. Make sure that the parameter names in props are the same as those passed by the parent component
props: ['zoo'].methods: {
testFun() {
this.$emit('handle'.'123')}}}</script>
Copy the code
Third, summary
Use the inheritAttrs attribute to pass data from component A to component C using concise code.
Notice We are attaching V-on = “$Listeners” to COMPONENT B and listening for events triggered by component C on component A. I can pass the data from component C to component A.