sourcecode

Vue 컴포넌트를 소품 및 슬롯 기본값으로 확장하는 방법

copyscript 2022. 8. 10. 22:16
반응형

Vue 컴포넌트를 소품 및 슬롯 기본값으로 확장하는 방법

사용하고 있다bootstrap-vue내 어플리케이션에도 있고 테이블도 많은데 모두 같은 보일러 플레이트 코드를 가지고 있어다음은 보일러 플레이트의 예를 제시하겠습니다.

<b-table
  :items="someItemList"
  :busy="someItemList === null"
  :empty-text="$t('notFound')"
  :empty-filtered-text="$t('notFound')"
  no-sort-reset
  show-empty
  striped
  hover
>
  <div slot="table-busy" class="text-center my-3">
    <b-spinner class="align-middle"/>
  </div>
</b-table>

물론 이 보일러 플레이트를 커스텀컴포넌트와 같은 일반적인 모듈로 분류하여 새로운 테이블의 시작점은 다음과 같습니다.

<my-awesome-table :items="someItemList">
</my-awesome-table>

궁극적으로, 저는my-awesome-table평소와 다름없이 행동하다b-table하지만 이 보일러 플레이트는 모두 세팅되어 있고, 필요에 따라 추가 소품이나 슬롯을 설치할 수 있습니다.

하지만 어떻게 해야 할지 모르겠어요.시도했습니다.

  • 래퍼 컴포넌트를 만들지만, 기본 컴포넌트의 모든 기능을 공개하는 데 어려움을 겪고 있습니다.b-table
  • 확장b-table컴포넌트입니다만, 보일러 플레이트 템플릿에 설정한 소품 및 슬롯 값을 설정하는 데 어려움을 겪고 있습니다.

소품 및 슬롯의 기본값을 설정할 수 있는 커스텀 컴포넌트를 작성하려면 어떻게 해야 합니까?

템플릿을 원하는 경우 다음과 같은 래퍼 구성 요소를 만들 수 있습니다.

  1. 에 할당하다b-table부모로부터의 Atribute를 바인드 합니다.
<b-table v-bind="$attrs" ...>
  1. 에 할당하다b-table부모로부터의 이벤트청취자를 연결합니다.
<b-table v-on="$listeners" ...>
  1. 임의의 슬롯을 통과시키다b-table:
<b-table ...>
  <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
    <slot :name="slot" v-bind="scope" />
  </template>
</b-table>

결과는 다음과 같습니다.

<template>
  <b-table
    your-prop-a
    your-prop-b
    your-prop-c
    v-bind="$attrs"
    v-on="$listeners"
  >
    <template v-for="(_, slot) of $scopedSlots" v-slot:[slot]="scope">
      <slot :name="slot" v-bind="scope" />
    </template>
  </b-table>
</template>

b-table 래퍼 편집

이 상황에서는 기능하는 컴포넌트가 필요합니다.테스트되지 않았지만 다음과 같은 방법을 시도해 보십시오.

마이 테이블표시하다

export default {
  functional: true,

  render(h, ctx) {
    // Get data from the parent component
    const {
      someItemList,
      $t,
    } = ctx.parent

    return h('b-table', {
      // Pass on the full data object
      ...ctx.data,

      // Extend the props
      props: {
        items: someItemList,
        busy: someItemList === null,
        emptyText: $t('notFound'),
        emptyFilteredText: $t('notFound'),
        noSortReset: true,
        showEmpty: true,
        striped: true,
        hover: true,

        // Override the above default prop values with any props provided
        ...ctx.props,
      },
    }, [
      // Provide a default rendering for the table-busy slot
      // if one is not provided
      !ctx.slots()['table-busy'] && h('div', {
        slot: 'table-busy',
        staticClass: 'text-center my-3',
      }, [
        h('b-spinner', { staticClass: 'align-middle' })
      ],

      // Append any additional children
      ...(ctx.children || [])
    ])
  }
}

그 후 다음과 같이 사용할 수 있습니다.

<my-awesome-table
  :items="otherList"
  :busy="isBusy"
>
</my-awesome-table>

<my-awesome-table>
  <div slot="table-busy">My custom busy slot</div>
  <div slot="something-else">Some other slot</div>
</my-awesome-table>

디폴트 프로포드는 다음과 같은 가치를 갖는다는 점에 주의해 주십시오.<my-awesome-table>용도는 부모 컴포넌트에 따라 크게 달라지지만, 어느 정도의 엄격한 관리를 원하는지는 사용자에게 달려 있습니다.

이 방법의 단점은 렌더링 함수를 손으로 작성해야 한다는 것입니다.Vue 템플릿 컴파일러는 기능 컴포넌트에 대한 지원이 매우 제한적이지만, 기능 컴포넌트를 구성하려고 할 때마다 후회하고 있습니다(템플릿은 쉽게 코드로 표현할 수 있는 것으로 인해 혼란스러워질 수 있습니다).

언급URL : https://stackoverflow.com/questions/57493900/how-to-extend-vue-component-with-default-values-for-props-and-slots

반응형