Vue 3 如何使组件的某一个部分继承外部属性

3,827 阅读1分钟

在写 Vue3 项目的过程中注意到当父组件给子组件传属性和事件时默认是将其绑定到子组件的根元素上,而我希望能绑定到子组件的指定元素上该如何写呢?

举个栗子:

父组件: ButtonDemo.vue

<template>
    <h2>示例1</h2>
    <div>
        <Button 
        @click="onclick"
        @focus="onClick"
        @mouseover="onClick">
        你好
        </Button>
    </div>
</template>

子组件:Button.vue

<template>
    <div >
        <button>
        	<slot/>
    	</button>
    </div>
</template>

默认将 Button 上的所有属性都绑到其根元素 div 上,我想绑到 button 元素上怎么办?

需求一:指定元素拥有全部属性

  • 使用 inheritAttrs: false 可以取消默认绑定
  • 使用 $attrs 或者 context.attrs 获取所有属性
  • $attrs 以对象的形式展示
// Button.vue 使用 $attrs 
<template>
   <div >
       <button v-bind="$attrs">
       <slot/>
   </button>
   </div>
</template>
<script lang="ts">
export default {
   inheritAttrs:false,
}
</script>
// Button.vue 使用 context.attrs 
<template>
   <div >
       <button v-bind="attrs">
       <slot/>
   </button>
   </div>
</template>
<script lang="ts">
export default {
   inheritAttrs:false,
   setup(props,context){
       const attrs = context.attrs
       return {attrs}
   }
}
</script>

需求二:指定元素拥有部分属性即批量绑定属性

将 attrs 分离

  • 使用 const {a,b, ...xxx} = context.attrs 将属性分开
  • ... 即扩展操作符 将 onClick 事件给 div,其余给 button
<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>

总结

  • 默认所有属性都绑定到根元素
  • 使用 inheritAttrs: false 可以取消默认绑定
  • 使用 $attrs 或者 context.attrs 获取所有属性
  • 使用 v-bind="$attrs" 批量绑定属性
  • 使用 const {size, level, ...xxx} = context.attrs 将属性分开

获取外部属性怎么没用到 props 呢?指路博客:了解 props 和 attars