【问题标题】:How to extend a Vue component with slots如何使用插槽扩展 Vue 组件
【发布时间】:2021-03-07 18:53:22
【问题描述】:

我想获得一个第三方库组件,再添加一个元素,并像往常一样使用这个第三方。

例子:

<third-party foo="bar" john="doe" propsFromOriginalLibrary="prop">
  <template v-slot:top=v-slot:top={ props: test }>
    Some text on third-party component slot
  </template>
</third-party>

想编码为:

<my-custom-component propsFromOriginalLibrary="prop">
  <template v-slot:top={ props: test }>
    Some text on third-party component slot
  </template>
</my-custom-component>

两个示例的工作方式相同。我能够通过以下方式获得所有道具:

<third-party v-bind="$attrs">

但不确定如何处理插槽

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component vuetify.js


    【解决方案1】:

    你可以这样做:

    my-custom-component模板:

    <template>
      <third-party v-bind="$attrs">
        <template v-slot:top="slotProps">
          <slot name="top" v-bind="slotProps"></slot>
        </template>
      </third-party>
    </template>
    

    发生了什么:

    1. 插入第三方组件和v-bind$attrs
    2. 引用其top
    3. 自定义组件有一个插槽,该插槽被传递到第三个插槽
    4. 自定义槽具有相同的名称,因此它可以是 v-slot 与父级相同的方式
    5. 自定义插槽 v-binds 所有第 3 方 slotProps 传递给父母

    您可以使用v-for 来避免对每个插槽的内部模板进行硬编码。例如,如果您想公开两个插槽,topbottom

    <template>
      <third-party v-bind="$attrs">
        <template v-for="slot in ['top','bottom']" v-slot:[slot]="slotProps">
          <slot :name="slot" v-bind="slotProps"></slot>
        </template>
      </third-party>
    </template>
    

    演示:

    Vue.component('third-party', {
      props: ['background'],
      template: `
      <div class="third" :style="{ background }">
        3rd party slot:
        <div class="third-slot">
          <slot name="top" :props="props"></slot>
        </div>
      </div>
      `,
      data() {
        return {
          props: 'Third party Prop'
        }
      },
    })
    
    Vue.component('my-custom-component', {
      template: `
      <div>
        <component is="third-party" v-bind="$attrs">
          <template v-for="slot in ['top']" v-slot:[slot]="slotProps">
            <slot :name="slot" v-bind="slotProps"></slot>
          </template>
        </component>
      </div>
      `
    })
    
    /***** APP *****/
    new Vue({
      el: "#app"
    });
    .third,.third-slot {
      padding: 10px;
    }
    .third-slot {
      background: #cccccc;
      border: 1px solid #999999;
      font-weight: bold;
    }
    <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
    <div id="app">
      <third-party background="#eeeeff">
        <template v-slot:top="{ props: test }">
          Some text on third-party component slot
          <div>{{ test }}</div>
        </template>
        
      </third-party>
    
      <my-custom-component background="red">
        <template v-slot:top="{ props: test }">
          Some text on third-party component slot
          <div>{{ test }}</div>
        </template>
      </my-custom-component>
    </div>

    有趣:你甚至可以让被包裹的组件像&lt;component :is="thirdpartyName"&gt;和槽名数组一样动态化;甚至从外部传递此信息以获得完全通用的包装器。但是这里没有必要

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 2019-08-19
      • 2017-08-19
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      相关资源
      最近更新 更多