前言——在Vue3里父组件调用子组件传属性时,默认传到根节点。
<!-->Dad <-->
<template>
<Button message="i'm Dad" @click="mes">按钮</Button>
</template>
<script lang="mes">
import Button from '....'
export dafult{
components:{Button},
setup(){
const mes = ()=> console.log('hi');
return {mes};
},
</script>
<!-->Son <-->
<template>
<button> <slot/> </button>
</template>
Dad组件在调用 Son组件时,传了两个属性 默认在button元素上 实际开发需求多变,
- 假设button元素上面有一个div,点击button在div之外的区域也会调用click,怎么办?去掉默认继承 就好。
<!-->Son <-->
<template>
<div>
<button v-bind="$attrs"> <slot/> </button>
</div>
</template>
<script lang="ts">
export dafult{
inheritAttrs:false;
}
</script>
inheritAttrs 为false 即可去掉默认继承,并给button绑定父所传 属性。
- 需求又变了,我还有其他属性要传,不能都给button
<!-->Son 组件<-->
<template>
<div :message="message">
<button v-bind="other"> <slot/> </button>
</div>
</template>
<script lang="ts">
export dafult{
inheritAttrs:false;
setup(props,context){
const {message,...other} = context.attrs
return {message,other}
}
}
</script>
context.attrs 跟$attrs 都是父传来的属性。这样分开获得父传来的属性分别给不同元素绑定。
总结: 1. inheritAttrs set false 可取消默认继承:inheritAttrs:false; 2. attrs" 即可。 4. 在setup()里可用第二个参数context.attrs 分开属性给不同元素绑定属性
拓展:
我们知道props也是接受父组件所传属性,props跟attrs) 有什么区别
- props 需要先声明才能取值,$attrs 不需要先声明;
<!-->Son 组件<-->
<script lang="ts">
export dafult{
inheritAttrs:false;,
props:{
message:String //类型声明
}
setup(props,context){
console.log({...props})
console.log({context.attrs})
}
}
</script>
你会发现context.attrs 里没有message属性了。在props里声明$attrs里没有 反之亦然
试一试:1.不声明props里message。在setup里打印props和context.attrs 看看props是否为空验证是不是需要先声明?;
- props是不接受事件的,而$attrs接受。
- props接受除String以外的类型,如:Boolean,而attrs不接受