首页 文章

如何封装/包装VueJS组件?

提问于
浏览
0

Hi everybody, please pardon my english :-)

我有一个可以采用动态插槽的Vue组件(插槽的名称将取决于道具) .

我在几个地方使用它,一些插槽总是存在 .

为了避免冗余,我正在寻找一种方法来创建一个“包装”最终组件的组件,以允许我只定义附加插槽 .

如果有一种“明显”的方式来实现它,我可能会错过它:-)

代码示例

没有“换行组件”

<b-table
  show-empty
  small
  hover

  [...some others and always present props...]

  :items="aDataVarThatWillChangeBasedOnTheContext"

  [...some others and uniq props...]
>
  <template slot="same-1">
   A slot that will always be present with the same content (for example, a checkbox in the first column)
  </template>

  <template slot="same-2">
   A slot that will always be present with the same content (for example, some action buttons in the last column)
  </template>

  [...some others and always present slots...]

  <template slot="not-the-same">
   A slot that is only used in this context (for example, a duration based on a row timestamp and a timestamp picked by the user)
  </template>

  [...some others and uniq slots...]
</b-table>

带有“换行组件”

<my-b-table
  :items="aDataVarThatWillChangeBasedOnTheContext"
>
  <template slot="not-the-same">
   A slot that is only used in this context (for example, a duration based on a row timestamp and a timestamp picked by the user)
  </template>
</my-b-table>

注意:动态插槽名称不可预测 . 如果我突然需要一个“foo”列,我应该能够传递一个“foo”插槽(以及一个“HEAD_foo”插槽,在我的情况下)

一些研究

我读了here

它们(功能组件)作为包装组件也非常有用 . 例如,当您需要:以编程方式选择其中一个其他组件来委派给子项,道具或数据,然后再将它们传递给子组件

并且“在将子项,道具或数据传递给子组件之前对其进行操作”似乎正是我所需要的 .

我看了渲染函数,但很多东西似乎没有实现,比如v模型,我很难弄清楚如何传递动态插槽......

Thank you in advance for your(s) answer(s) !

up:在07.03.2018,我仍然不知道如何解决这个案子

2 回答

  • 0

    找到了那个月前我不清楚的答案 .

    (“动态”在这里表示“组件未明确声明,但由父级给出”)

    包装组件

    可以通过 createElement 函数的 options 对象动态地提供道具和作用域槽 .

    "Simple" createElement 函数的 childs 数组可以动态地给出插槽 .

    包裹的组件

    除非组件功能正常,否则道具不能是动态的 .

    始终可以动态检索插槽 .

    仅当组件不起作用时,才能检索范围内的插槽 .

    结论

    同时拥有动态道具和范围插槽是不可能的......

    但是可以声明所有需要的道具,然后使用“非功能”组件作为包装和包装 .


    如何

    从非功能组件中检索

    var component = Vue.component('component-name', {
      props: ['name', 'of', 'the', 'props'],
      [...]
      aMethod: function () {
        this._props // all the declared props
        this.$slots // all the slots
        this.$scopedSlots // all the scoped slots
      }
    });
    

    从功能组件中检索

    var component = Vue.component('component-name', {
      functional: true,
    
      render: function (createElement, context) {
        context.props // all the props
        context.children // all the slots as an array
        context.slots() // all the slots as an object
      }
    });
    

    给孩子组件

    var component = Vue.component('component-name',{render:function(createElement){return createElement(childComponent,{props:propsToGive,scopedSlots:scopedSlotsToGive},[//非范围的插槽赋予createElement('slot- tag-name',{slot:'slot-name'})]);}});


    参考文献

    https://vuejs.org/v2/guide/render-function.html

    https://vuejs.org/v2/guide/render-function.html#createElement-Arguments

    https://vuejs.org/v2/guide/render-function.html#Functional-Components


    沙盒

    https://jsfiddle.net/5umk7p52/

  • 1

    只需从定制的 <b-table> 中制作常规组件即可 .

    您需要为组件定义 items prop作为 <b-table> <b-table> 组件传递 .

    并且,要为组件定义 slot ,您需要使用 <slot> 标记,使用 name 属性指定名称 .

    如果您想在 <my-b-table> 组件中访问 <b-table> 组件中的一个插槽,只需将 <slot> 标记作为自定义组件中插槽的内容传递即可 .

    它看起来像这样:

    Vue.component('my-b-table', {
      template: `
        <b-table
          show-empty
          small
          hover
          :items="items"  
        >
          <template slot="same-1">
            Content to pass to the b-table's slot
          </template>
    
          <slot name="not-the-same">
            A slot that is only used in this context
          </slot>
    
          <template slot="last_edit">
            <slot name="last_edit">
              A slot to pass content to the b-table component's slot
            </slot>
          </template>
        </b-table>
      `,
      props: { items: Array },
    });
    

相关问题