访问Vue中的任意插槽

时间:2018-09-15 20:32:52

标签: typescript vuejs2

说我想创建一个多层组件,以便像'Tab' Ui这样重复使用。

因此使用中的开发人员可以写:

savedLeagueId = String.valueOf(getIntent().getIntExtra("leagueId",2));

基本上,他们将以这样的方式使用Tabs和Tab组件:我不知道开发人员将在Tabs中使用多少Tab组件。如何访问Tab组件,例如,按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> this.$children,但实际上无法访问Tab数据来显示和隐藏它。公平地说,我正在用Typescript写作,因此它可能会更困难。

类似的东西:

this.slots.default

我已经在Vue中查看了一些Tabs的GitHub库,逻辑似乎很复杂。我假设从插槽/子代的存在来看,有一种更直接的方法来访问子代组件。也许这对我来说太过希望了。

如果您不知道子插槽中有多少个子插槽(即您没有在父组件中显式写入它们),那么谁知道如何访问,传递或更改子插槽中的数据?

2 个答案:

答案 0 :(得分:2)

如果问题是您必须等到挂载制表符组件,则存在mounted生命周期挂钩。正如Vue docs所述,使用$children属性存在潜在的问题:

  

请注意,没有为$ children提供订单保证,并且该订单不具有反应性。如果您发现自己试图使用$ children进行数据绑定,请考虑使用Array和v-for生成子组件,然后将Array用作真相。

由于不能保证顺序,因此不能保证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>

答案 1 :(得分:1)

我的问题的一部分(似乎是)Tab的created()函数在挂载Tab组件之前启动,因此它们可能存在或不存在。通过使用超时调用初始选择,我可以使用

(this.$children[index] as any)["show"] = true;

有人知道如何检查(立即)子组件的安装时间吗?我做了一些搜索,却找不到正确的答案。