通常vue中父子组件传值,我们一般都是用props及$emit来实现,这没毛病,但是如果存在多代呢?例如爷、父、子、孙、太孙……等多代存在的时候呢?当然你用props及$emit一层层传递也没毛病,唯一的问题就是很麻烦……
而vue在2.4.0版本中,为了解决这个问题,便提出了$attrs和$listeners,请见以下示例:
示例一:不绑定$attrs时,看下每个下级组件,$attrs默认会接收到什么?
index.vue文件(爷)
<template>
<A
fromIndex="我是来自index里的数据"
/>
</template>
<script>
import A from './a'
export default {
components: {
A
}
}
</script>
a.vue文件(父)
<template>
<div>
父组件: {{$attrs}}
<B
fromA="我是来自A里的数据"
/>
</div>
</template>
<script>
import B from './b'
export default {
components: {
B
}
}
</script>
b.vue文件(儿)
<template>
<div>
子组件: {{$attrs}}
<C
fromB="我是来自B里的数据"
/>
</div>
</template>
<script>
import C from './c'
export default {
components: {
C
}
}
</script>
c.vue文件(孙)
<template>
<div>孙子组件: {{$attrs}}</div>
</template>
<script>
export default {
methods: {
}
}
</script>
此时页面显示为:
总结:不绑定$attars时,$attars默认只能接收到对应父组件里的属性值,即使子组件未定义props
示例二:绑定$attars,看下对应下级组件会接收到什么?
index.vue文件(爷)
<template>
<A
fromIndex="我是来自index里的数据"
/>
</template>
<script>
import A from './a'
export default {
components: {
A
}
}
</script>
a.vue文件(父)
<template>
<div>
父组件: {{$attrs}}
<B
fromA="我是来自A里的数据"
v-bind="$attrs"
/>
</div>
</template>
<script>
import B from './b'
export default {
components: {
B
}
}
</script>
b.vue(儿)
<template>
<div>
子组件: {{$attrs}}
<C
fromB="我是来自B里的数据"
v-bind="$attrs"
/>
</div>
</template>
<script>
import C from './c'
export default {
components: {
C
}
}
</script>
c.vue(孙)
<template>
<div>孙子组件: {{$attrs}}</div>
</template>
<script>
export default {
methods: {
}
}
</script>
此时页面展示:
总结:绑定$attars后,我们会发现,即使孙子组件的父组件未定义fromIndex属性,但依旧可以直接接收到爷爷组件里的值
最后:v-on="$listeners"和v-bind=$attars差不多,只不过是对应$emit事件,可以将孙子组件的$emit直接派发到爷爷组件数据去,感兴趣的,自己去试试吧!