programing

Vue에서 임의 슬롯 액세스

goodcopy 2022. 7. 12. 21:55
반응형

Vue에서 임의 슬롯 액세스

를 들어, '탭' 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>

기본적으로 Tabs와 Tab 컴포넌트는 개발자가 Tabs에서 사용하는 Tab 컴포넌트의 수를 알 수 없는 방식으로 사용됩니다.예를 들어 탭별 UI 기능을 표시 및 숨기기 위해 탭 구성 요소에 액세스하는 방법은 무엇입니까?

i i사았 i i 。this.$children ★★★★★★★★★★★★★★★★★」this.slots.default그러나 실제로 Tab 데이터에 액세스하여 표시하거나 숨길 수 없었습니다.공평하게 말하면, 저는 타이프 스크립트로 쓰고 있는데, 그것 때문에 문제가 더 어려워질 수도 있습니다.

예를 들어 다음과 같습니다.

<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 libs를 몇 가지 살펴봤는데 논리가 매우 복잡해 보입니다.슬롯/자녀의 존재로 볼 때, 아동 컴포넌트에 액세스하기 위한 보다 간단한 방법이 있다고 생각합니다.아마도 그건 내 입장에서 너무 희망적인 것 같아요.

자녀 수가 얼마나 될지 모르는 경우(부모 컴포넌트에 명시적으로 기입하지 않은 경우) 자녀 슬롯의 데이터에 액세스, 패스 또는 변경하는 방법을 알고 있는 사람이 있습니까?

탭 컴포넌트가 마운트될 때까지 기다려야 하는 경우에는 마운트된 라이프 사이클 훅이 존재합니다.를 사용하는 경우 잠재적인 문제가 있습니다.$childrenVue 문서에 설명된 대로 속성:

$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 you 쓸 수 요.을 사용하다

<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>

는, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.created()Tabs 기능은 Tab 구성 요소가 마운트되기 전에 실행되므로 구성 요소가 존재하거나 존재하지 않을 수 있습니다.Timeout과 으로써 "Timeout"을 할 수 .

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

(즉시) 어린이 구성 요소가 장착되었는지 확인하는 방법을 아는 사람이 있습니까?나는 몇 가지 검색해 보았지만 적절한 답을 찾을 수 없었다.

이 문제를 해결할 수 있었던 것은updated 라이프 사이클 후크this.$nextTick()컴포넌트가 갱신될 때마다 무엇인가를 실행할 수 있습니다(자녀 요소에 악시스가 투고되기를 기다리고 있었습니다).

정리하면 다음과 같습니다.

mounted() {
  // this makes reference to the children inside the (current) component slots
  const tabs: Tab[] = this.$vnode.componentInstance.$children as Tab[];
  setTabs(tabs);
}

updated() {
  this.$nextTick(function () {
    const updatedTabs: Tab[] = this.$vnode.componentInstance.$children as Tab[];

    if (updatedTabs.length > this.tabs.length) setTabs(updatedTabs);
  });
}

setTabs(updatedTabs: Tab[]) {
  this.tabs = updatedTabs;
  // Do some more stuff here if you want (like filtering or ordering)
}

언급URL : https://stackoverflow.com/questions/52348634/accessing-arbitrary-slots-in-vue

반응형