父组件
<template>
<div>Button 示例</div>
<h1>示例1</h1>
<div>
<Button @click="onClick"
@focus="onClick"
@mouseover="onClick"
>你好</Button>
</div>
</template>
<script lang="ts">
import Button from "../lib/Button.vue";
export default {
components:{
Button:Button
},
setup(){
const onClick=()=>{
console.log('hi');
};
return {onClick}
}
}
</script>
子组件
<template>
<div>
<button >
<slot />
</button>
</div>
</template>
这时候虽然没有在子组件的button上绑定click,mouseover等事件,但是,仍然可以发现在子组件上同样可以使用,而且连带外面的div都可以触发绑定的事件,这是因为vue3的所有属性会默认被绑到根元素。
要想去除这种继承关系,可以在子组件中声明inheritAttrs:false,然后把v-bind="$attrs"绑定到button元素上
子组件
<template>
<div>
<button v-bind="$attrs">
<slot />
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs:false
}
</script>
若想单个绑定事件,则可以用到context
子组件
<template>
<div @click="onClick">
<button @mouseover ="onMouseover" @focus="onFocus">
<slot />
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs:false,
setup(props,context){
const {onClick,onMouseover,onFocus} = context.attrs
return {onClick,onMouseover,onFocus}
}
}
</script>
es6的剩余操作符可以帮忙把属性分成两部分,如:
子组件
<template>
<div @click="onClick">
<button v-bind="rest">
<slot />
</button>
</div>
</template>
<script lang="ts">
export default {
inheritAttrs:false,
setup(props,context){
const {onClick,...rest} = context.attrs
return {onClick,rest}
}
}
</script>
注意: 子组件的元素除了button和根元素div以外不要放其他的元素,不然会导致属性绑定失效