typescript - PrimeVueで親コンポーネントから子コンポーネントにスロットを渡す方法は?
私はいくつかの PrimeVue コンポーネントをラップして、自分のコンポーネントライブラリを作ろうとしています。しかし、すべてのスロットはどのように扱えばよいのでしょうか?
一部の PrimeVue コンポーネントには多くのスロットがあるため、それぞれを個別に渡すのは非常に面倒です。
幸いなことに、親コンポーネントから子コンポーネントにすべてのスロットを渡すこの解決策を見つけました。
こちらは PrimeVue ドロップダウンコンポーネントでの使用例です:
<Dropdown v-bind="$attrs" >
<template v-for="(_, name) in $slots" #[name]="scope">
<slot :name v-bind="scope" />
</template>
</Dropdown>
残念ながら、PrimeVueでは動作しません。TypeScriptがDropdownSlotsにインデックスシグネチャがないことに関して、#[name]でこのエラーを出すためです:
要素は暗黙的に 'any' 型を持っています。なぜなら、'string | number' 型の式は 'DropdownSlots' 型のインデックスとして使用できないからです。
型 'DropdownSlots' には、型 'string' のパラメータを持つインデックス署名が見つかりませんでした。ts(7053)
何か回避策のアイデアはありますか?
回答 #1
TypeScriptのエラーが出ているからといって、コードが間違っているわけではありません。Vueのテンプレートは設計上現在型安全ではなく、型チェックにはサードパーティのツール(vue-tsc、IDEなど)が必要であり、それらには独自の癖がある場合があります。
子供やプロップスをテンプレートではなくレンダリング関数で変換する方が簡単です。これにより、テンプレートで型を使用することに関連する問題も回避できます。シンプルなラッパーコンポーネントの場合は次の通りです。
setup(props, { slots }) {
return () => h(Dropdown, props, slots);
}
回答 #2
これらのスロット転送に関連するすべての問題を解決するために、Vue Forward Slotsという素晴らしいパッケージを見つけました: https://www.npmjs.com/package/vue-forward-slots
デフォルトスロットを含むすべてのスロットを転送するために、このように使っています:
<ForwardSlots :exclude="[]">
<Dropdown v-bind="$attrs" />
</ForwardSlots>
いつかこのようなものが core vue.js に取り入れられることを願っています。
