preface
When multi-level component nesting needs to pass data, the common method used is through VUEX. But just passing data around without intermediate processing and using VUEX is overkill. Therefore, there are $listeners and $attrs, which are often used with inheritAttrs.
$attrs
- Attribute passed from parent to custom child, if not
prop
Receive is automatically set to the outermost label inside the child component, if yesclass
和style
It will merge the outermost tagclass
和style
. - If the child component does not want to inherit the parent component’s not
prop
Property, which can be usedinheritAttrs
Disable inheritance, then passv-bind="$attrs"
The non from the outsideprop
Property is set to the desired tag, but this does not changeclass
和style
.
InheritAttrs propertiesThe website links
2.4.0 new
-
Types: Boolean
-
Default value: true
-
Details:
Attribute bindings, which are not recognized as props in the parent scope, are “rolled back” by default and applied to the root element of the child component as normal HTML attributes. This may not always behave as expected when writing a component that wraps one target element or another. These default behaviors are removed by setting the inheritAttrs to false. These attributes are enabled by the (also new in 2.4) instance Property $attrs, which can be explicitly bound to non-root elements by V-bind.
Note: This option does not affect the class and style bindings.
Example:
The parent component
<template>
<my-input
required
placeholder="Please enter the content"
type="text"
class="theme-dark"
/>
</template>
<script>
import MyInput from './child'
export default {
name: 'parent'.components: {
MyInput
}
}
</script>
Copy the code
Child components
<template>
<div>
<input
v-bind="$attrs"
class="form-control"
/>
</div>
</template>
<script>
export default {
name: 'MyInput'.inheritAttrs: false
}
</script>
Copy the code
The child component does not accept the value passed from the parent component, nor does it have a binding, but it does have a v-bind=”$attrs” attribute, which it will automatically accept and bind
inheritAttrs: false
inheritAttrs: true
$Listeners
- listeners: contains objects in the parent scope
.native
Modifier of)v-on
Event listeners. It can go throughv-on="$listeners"
Passing in internal components – useful when creating higher-level components.
Here are just two examples of native events: focue and input
/ / the parent component
<template>
<my-input
required
placeholder
class="theme-dark"
@focue="onFocus"
@input="onInput"
>
</my-input>
</template>
<script>
import MyInput from './child'
export default {
components: {
MyInput
},
methods: {
onFocus (e) {
console.log(e.target.value)
},
onInput (e) {
console.log(e.target.value)
}
}
}
</script>
Copy the code
/ / child component
<template>
<div>
<input
type="text"
v-bind="$attrs"
class="form-control"
@focus="$emit('focus', $event)"
@input="$emit('input', $event)"
/>
</div>
</template>
<script>
export default {
name: 'MyInput'.inheritAttrs: false
}
</script>
Copy the code
Native events are a hassle, and every native event needs to be bound, but v-on=”$listeners” saves a lot of trouble
<input
type="text"
v-bind="$attrs"
class="form-control"
+ v-on="$listeners"
- @focus="$emit('focus', $event)"
- @input="$emit('input', $event)"
/>
Copy the code
This one line of code solves the problem of binding all native events