@[TOC]

background

The vueadmin-template project has two attributes v-bind=”$attrs” and v-on=”$linteners”, so I took a look at the two attributes and understood them through a simple demo test.

As we know, passing data to a subcomponent is done through the props property defined by the V-bind subcomponent, which only works between one-way, two-tier components. Similarly, event passing is also used to bind events to child components using V-on in the parent component, and then emitted by this.$emit in the child component to modify the parent component data.

So, in a multi-tier nested component, how does data transfer and event firing occur between the top component and the bottom component? For example, if component A refers to component B, and component B refers to component C, how to pass data from A to C? How do I trigger A method in C? These are $listeners and $attrs.

$attrs

$attrs is a built-in property that refers to all properties passed by the parent component, except the props property that the parent component defines itself. For example, component A references component B and binds three properties foo, coo, and COO1 to it:

<child-dom
  :foo="foo"
  :coo="coo"
  :coo1="foo"
  v-on:eventBindOnB="eventMethodInA"
>
Copy the code

$attrs = props: [‘foo’, ‘coo1’]; $attrs = coo (props); At this point, B references component C and passes it a property coo:

<child-dom-child 
:coo="coo1" 
msg="Configuration for component B, but not defined for component C"
v-bind="$attrs" 
v-on="$listeners" 
@change="eventMethodInB"></child-dom-child>
Copy the code

$attrs is null in the C component (child-dom-child), where props: [‘coo’, ‘coo1’] is defined. In the project referenced, you need to bind $attrs to C in component B, but tests found that without this binding, C also has $attrs by default, and can also get the value of the parent component.

$listeners

$Listeners are all listeners to the component, and can be bound to its child listeners via V-on =”$Listeners “.

In the previous example, the listener event that component B finally binds to component C is equal to the eventBindOnB event that A binds to B, plus the change event that B binds to C, which can trigger any event bound to C in C.

C event = A listener event eventBindOnB + B listener event changeCopy the code

Define A button in the C component to trigger the A component’s methods:

< button@click ="triggerMethodInA"> Click </button> method definitiontriggerMethodInA() {
   this.$emit('change'// Trigger B's listening event this.$emit(eventBindOnB) // Triggers A's listening event}Copy the code

Method definitions in component A:

methods: {
  eventMethodInA() {
    this.coo = 'I have been changed'
    this.msg = 'I have been changed11'
    console.log('change is trigger.')}}Copy the code

B component method definition:

methods: {
  eventMethodInB() {
   // this.coo1 = 'B Component change it '
    console.log('change is trigger.')}}Copy the code

This completes the logic for the bottom layer to trigger the top-level event in the nested component. Click the button of component C, and finally call A method of A to complete the modification of A data:

The revelation of

The parent component controls the props properties of the child component. Therefore, the parent component cannot modify its own props properties in the child component. Otherwise, vUE will report an error:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten 
whenever the parent component re-renders. 
Instead, use a data or computed property based on the prop's value. Prop being mutated: "coo1"Copy the code

To summarize the data and event triggering process for nested components:

This article
$attrs
$listeners

By knocking code, familiar with some ESLint specifications, but also incidentally verified the wisdom of ancestors: no other, only hand can be familiar!