## 事象 [[Vuetify3]]の`<v-badge>`をwrapしたコンポーネントを作り... `Badge.vue` ```html <script setup lang="ts"> defineProps<{ disabled: boolean; }>(); </script> <template> <v-badge v-if="!disabled"> <slot></slot> </v-badge> <template v-else> <slot></slot> </template> </template> ``` 以下のように利用する。 ```html <Badge :disabled="unreadCount === 0" color="primary" :content="unreadCount" location="top start" offset-x="32" offset-y="7" > <v-list-item prepend-icon="mdi-message-alert" title="重要なメッセージ確認" value="crucial-messages" :active="page === 'crucial-messages'" ></v-list-item> </Badge> ``` [[Chrome devtools]]にwarningが表示される。 ```warn App.vue:11 [Vue warn]: Extraneous non-props attributes (color, content, location, offset-x, offset-y) were passed to component but could not be automatically inherited because component renders fragment or text root nodes. at <Badge disabled=true color="primary" content=0 ... > at <VListChildren items= [] returnObject=false > at <VList nav="" onClick:select=fn<handleClickItem> > at <VNavigationDrawer expand-on-hover="" rail="" > at <VLayout key=0 > at <VApp> at <App> ``` ## 原因 [[defineProps (Vue)|defineProps]]で定義されていないpropsを渡しており、rootの要素が2つ以上存在するため。今のところ[[フォールスルー属性 (Vue)|Fallthrough Attributes]]はよしなに発動しているが、将来的には保証されない。 ## 解決方法 [[defineProps (Vue)|defineProps]]で定義をすればなおる... がこの場合はwarpperコンポーネントの性質上、土管として流し込みたいケースのはず。 その場合は[[フォールスルー属性を無効 (Vue)|Fallthrough Attributesを無効]]化し、明示的に`v-bind="$attrs"`でFallthroughしたい要素を指定するといい。 ```html <script setup lang="ts"> defineOptions({ inheritAttrs: false, }); defineProps<{ disabled: boolean; }>(); </script> <template> <v-badge v-if="!disabled" v-bind="$attrs"> <slot></slot> </v-badge> <template v-else> <slot></slot> </template> </template> ``` ## 参考 - [Vue.js](https://vuejs.org/guide/components/attrs.html#disabling-attribute-inheritance)