This article mainly introduces to you how to use the new $attrs and $listeners attributes in Vue v2.4. The article introduces it in detail through sample code, which will be a certain reference for everyone's study or work. Value, friends who need it, please follow me to learn together.
When multi-level component nesting needs to pass data, the usually used method is through vuex. If you just transfer data without intermediate processing, using vuex to process it would be a bit overkill. Vue version 2.4 provides another method, using v-bind="$attrs", to pass attributes in the parent component that are not considered props attribute binding to the child component, usually used with the interitAttrs option. The reason why these two attributes are mentioned is that the emergence of them makes cross-component communication between components concise and business clear without relying on vuex and event bus.
First analyze the following application scenarios:
As shown in the figure above, the three components A, B, and C are nested in sequence. According to Vue’s development habits, parent-child component communication can be achieved in the following ways:
A to B Passed to sub-components through props, B to A is achieved by $emit in the B component and v-on in the A component
By setting the global Vuex shared state, through computed The acquisition and update of data are achieved through calculated properties and commit mutations to achieve the purpose of communication between parent and child components.
Vue Event Bus uses Vue instances to implement event monitoring and publishing, and to achieve transfer between components.
Often when the data does not need to be global but only communicates between parent and child components, the first method is sufficient.
As shown above, A component and C component belong to a cross-multi-level component nesting relationship Relationship, in the past, if communication between the two needed to be achieved, it was often achieved through the following methods:
With the help of the transfer of the B component, props are passed from top to bottom in sequence, from bottom to top, $emit Event delivery achieves the effect of cross-level component communication
With the help of Vuex’s global state sharing
Vue Event Bus, using Vue instances, Implement the monitoring and publishing of events and the transfer between components.
Obviously, the first method through props and $emit makes the business logic between components bloated, and component B only acts as a transfer station. If you use the second Vuex method, it seems to be a bit overkill in some cases (it is just to realize a data transfer between components, not the concept of data sharing). The use of the third situation is found in actual project operations. If good event monitoring and release management cannot be achieved, it often easily leads to chaos in the data flow. In multi-person collaboration projects, it is not conducive to project maintenance.
The appearance of $attrs and $listeners solves the problem of the first situation. When component B passes props and events, there is no need to write redundant code. It just adds $attrs and $listeners. Just pass it up or down.
is as follows:
<template> <p id="app"> <child1 :p-child1="child1" :p-child2="child2" v-on:test1="onTest1" //此处监听了两个事件,可以在B组件或者C组件中直接触发 v-on:test2="onTest2"> </child1> </p> </template> <script> import Child1 from './Child1.vue'; export default { data () { return {}; }, components: { Child1 }, methods: { onTest1 () { console.log('test1 running...'); }, onTest2 () { console.log('test2 running'); } } }; </script>
<template> <p class="child-1"> <p>in child1:</p> <p>props: {{pChild1}}</p> <p>$attrs: {{$attrs}}</p> <hr> <!-- C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 --> <!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) --> <child2 v-bind="$attrs" v-on="$listeners"></child2> </p> </template> <script> import Child2 from './Child2.vue'; export default { props: ['pChild1'], data () { return {}; }, inheritAttrs: false, components: { Child2 }, mounted () { this.$emit('test1'); } }; </script>
Result:
in child1:
props: v_child1
$attrs: { “p-child2”: “v_child2”}
<template> <p class="child-2"> <p>in child2:</p> <p>props: {{pChild2}}</p> <p>$attrs: {{$attrs}}</p> <hr> </p> </template> <script> export default { props: ['pChild2'], data () { return {}; }, inheritAttrs: false, mounted () { this.$emit('test2'); } }; </script>
Result:
in child2:
props: v_child2
$attrs: {}
$attrs
Contains attribute bindings (except class and style) that are not considered (and are not expected to be) props in the parent scope. When a component does not declare any props, all parent scope bindings (except class and style) will be included here, and internal components can be passed in through v-bind="$attrs" - when creating higher-level components Very useful.
$listeners
Contains v-on event listeners in the parent scope (without .native decorator). This can be passed into internal components via v-on="$listeners" - very useful when creating higher level components.
inheritAttrs
By default attribute bindings in the parent scope that are not recognized as props will "fall back" and be treated as normal HTML Attributes are applied to the root element of the child component. When writing a component that wraps a target element or another component, this may not always conform to the expected behavior. By setting inheritAttrs to false, these default behaviors will be removed. These features can be enabled through the instance attribute $attrs (also new in 2.4), and can be explicitly bound to non-root elements through v-bind.
The use of the above features can completely reduce the complexity of component cross-level props and event delivery without using Vuex and event bus.
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
related articles:
How to use jquery to modify the background style by clicking a link
About the ajax synchronization operation and the browser suspended animation (detailed tutorial)
How to monitor the number of words entered in the text box in js (detailed tutorial)
What are the efficient algorithms in JavaScript
The above is the detailed content of A detailed introduction to the $attrs attribute in Vue. For more information, please follow other related articles on the PHP Chinese website!