'Tab'Uiのように再利用するための多層コンポーネントを作成したいとします。
したがって、使用している開発者は次のように書くことができます。
<tabs>
<tab label="My First Tab">
Content for first tab which could contain components, html, etc.
</tab>
<tab label="My Second Tab">
More Content
</tab>
</tabs>
基本的に、彼らはタブとタブコンポーネントを使用するので、開発者がタブで使用するタブコンポーネントの数がわかりません。タブコンポーネントにアクセスして、たとえば、タブUI機能ごとに表示および非表示にするにはどうすればよいですか?
使用this.$children
してみましthis.slots.default
たが、実際にはタブデータにアクセスして表示および非表示にすることができませんでした。公平を期すために、私はTypescriptで書いていますが、そのため問題はもっと難しいかもしれません。
何かのようなもの:
<template>
<div class="tabs">
<slot /> <!-- Location of the Tab's -->
</div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component({
...
})
export default class Tabs extends Vue {
public tabs: any[] = [];
public created() {
this.tabs = this.$slots.default;
// this.tabs is a set of VNode's,
// I can't figure out how to access the components
// I see a prop 'componentInstance' but when I try to
// access it, it says undefined
// this.select(0);
let tab = this.tabs.find((obj: any, index: number) => {
return index === 0;
}); // tab is undefined :(
}
public select(index: number) {
(this.$slots.default[index] as any).show = true;
// Accessing Vnode instead of Component :(
// this.$children[0]["show"] = true; // Read only :(
// this.tabs[index].show = true; // blerrggg :(
// Vue.nextTick();
}
}
</script>
Vueのタブ用のGitHubライブラリをいくつか見てきましたが、ロジックは非常に複雑なようです。スロット/子の存在から、子コンポーネントにアクセスするためのより簡単なアプローチがあると思います。多分それは私の側では過度に希望的です。
子スロットにいくつの子があるかわからない場合(つまり、親コンポーネントに明示的に書き込んでいない場合)、子スロットのデータにアクセス、受け渡し、または変更する方法を知っている人はいますか?
タブコンポーネントがマウントされるまで待たなければならないという問題がある場合、マウントされたライフサイクルフックはこの種のもののために存在します。$children
ただし、Vueのドキュメントで概説されているように、プロパティの使用には潜在的な問題があります。
$ childrenの注文保証はなく、反応的ではないことに注意してください。データバインディングに$ childrenを使用しようとしていることに気付いた場合は、配列とv-forを使用して子コンポーネントを生成し、その配列を信頼できる情報源として使用することを検討してください。
注文は保証されていないので、this.$children[index]
あなたが期待するタブを与えることは保証されていません。
v-for
と配列を使用して提案されたアプローチを使用すると、次のようになります。
<template>
<div class="tabs">
<tab v-for="(tabName, index) in tabs" :key="tabName" :label="tabName" :ref="`tab-${index}`">
<slot :name="tabName"></slot>
</tab>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
@Component({
...
})
export default class Tabs extends Vue {
@Prop(Array) tabs: string[];
public mounted() {
this.select(0);
}
public select(index: number) {
this.$refs[`tab-${index}`].show = true;
}
}
</script>
スロットをタブ内に配置して、すべての子コンポーネントがタブコンポーネントにラップされることを確認します。つまり、すべてのtabs
子がtab
コンポーネントであることが保証され、すべての子が$refs
期待されるtab
プロパティを持ちます。あなたはこのようにこれを使うでしょう:
<tabs :tabs="['My First Tab', 'My Second Tab']">
<template slot="My First Tab">
Content for first tab which could contain components, html, etc.
</template>
<template slot="My Second Tab">
More content
</template>
</tabs>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加