Vue中的$attrs和$listener
大家在组件开发中肯定遇到过父组件需要向子组件传递数据和事件的问题,以往我们是这样解决的:
父组件代码:
1 <template> 2 <div id="father"> 3 <child :tempdata="temp" @fatherFn="tempFn"><child> 4 div> 5 template> 6 <script> 7 export default { 8 data() { 9 temp: 'click here!' 10 }, 11 method: { 12 tempFn: function(message) { 13 console.log(message); 14 } 15 } 16 } 17 script>
子组件代码:
1 <template> 2 <div id="child"> 3 <span @click="childClick(message)">{{ tempdata }}span> 4 div> 5 template> 6 <script> 7 export default { 8 props: { 9 tempdata: { 10 type: String, 11 default: '' 12 } 13 }, 14 data() { 15 return { 16 message: 'i am child' 17 } 18 }, 19 methods: { 20 childClick: function(message) { 21 this.$emit('fatherFn', message); 22 } 23 } 24 } 25 script>
这样我们完成了从父组件传递数据已经方法到子组件,但是如果是向子组件的子组件传递信息呢?显然我们需要换一种更加简单的方式实现祖孙组件之间的数据传输,小二上代码:
1 // father组件 2 <template> 3 <div id="father"> 4 <child :temp="tempdata" @tempFn="fatherFn" :prop='$attrs不会传递child组件中定义的props 5 值'> 6 child> 7 div> 8 template> 9 <script> 10 import Child from './child' 11 export default { 12 component: { Child }, 13 data() { 14 tempdata: 'i am father' 15 }, 16 methods: { 17 fatherFn: function() { 18 console.log('father function!'); 19 } 20 } 21 } 22 script> 23 24 // child组件 25 <template> 26 <div id="child"> 27 <son v-bind="$attrs" v-on="$listener">son> 28 div> 29 template> 30 <script> 31 import Son from './son' 32 export default { 33 component: {Son}, 34 props: { 'prop' }, 35 data() { 36 return {} 37 }, 38 mounted() { 39 // 结果显示为$attrs.temp,不包含prop 40 console.log(this.$attrs) 41 this.$emit('tempFn') 42 }, 43 methods: {} 44 } 45 script> 46 47 // son组件 48 <template> 49 <div id="son"> 50 {{ $attrs.temp }} 51 div> 52 template> 53 <script> 54 export default { 55 prop: {}, 56 data() { 57 return {} 58 }, 59 mounted() { 60 this.$emit('tempFn') 61 }, 62 methods: {} 63 } 64 script>
综上,可知:
$listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,它可以通过 v-on=”$listeners” 传入内部组件。
$attrs包含了父作用域中非props 特性绑定的属性 (class 和 style 除外)。当一个组件没有声明任何 props 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件。
--------------------------------------
新增理解
其实$attrs,$listeners,$props都是一样的,我们可以通过当前组件实例访问到,具体包含如下:
$attrs:当前组件的属性,通俗的讲也就是在组件标签定义的一系列属性,如input的value,placeholder等,但是不包括在当前组件里面定义的props属性
$listeners:当前组件监听的事件,通俗的讲也就是在使用组件的时候在标签中定义的事件,如@input,以及一些自定义事件@tempFn等
$props:当前组件从父组件那里接收的参数,通俗的讲和$attr差不多,但是只包括在当前组件中定义了的props属性
通俗的讲$attrs+$props = 在使用组件时定义的所有属性,不包括事件
那么在当前组件中使用v-bind="$attrs",v-bind="$props",v-on="$listeners"也就是把之前父组件那里给它的属性再全部传到它的子组件。