Vue.js 如何封装/包装VueJS组件?

Vue.js 如何封装/包装VueJS组件?,vue.js,vuejs2,vue-component,Vue.js,Vuejs2,Vue Component,大家好,请原谅我的英语:-) 我有一个Vue组件,可以使用动态插槽(插槽的名称取决于道具) 我在几个地方使用它,一些插槽总是存在 为了避免冗余,我正在寻找一种方法来创建一个“包装”最终组件的组件,以允许我只定义额外的插槽 如果有一个“明显的”方法来实现它,我可能会错过它:-) 代码示例 没有“包裹组件” 始终包含相同内容的插槽(例如,第一列中的复选框) 始终显示相同内容的插槽(例如,最后一列中的某些操作按钮) […其他一些和始终存在的插槽…] 仅在此上下文中使用的插槽(例如,基于行时间戳和用户

大家好,请原谅我的英语:-)

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

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

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

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

代码示例 没有“包裹组件”

始终包含相同内容的插槽(例如,第一列中的复选框)
始终显示相同内容的插槽(例如,最后一列中的某些操作按钮)
[…其他一些和始终存在的插槽…]
仅在此上下文中使用的插槽(例如,基于行时间戳和用户选择的时间戳的持续时间)
[…其他一些和uniq插槽…]
使用“包裹组件”

仅在此上下文中使用的插槽(例如,基于行时间戳和用户选择的时间戳的持续时间)
注意:动态插槽名称不可预测。 如果我突然需要一个“foo”列,我应该能够通过一个“foo”槽(在我的例子中,还有一个“HEAD\u foo”槽)

一些研究 我读到:

它们(函数组件)作为包装器组件也非常有用。例如,当您需要:

  • 以编程方式选择要委派到的其他几个组件之一
  • 在将子组件、道具或数据传递给子组件之前,操作它们
“在将子组件、道具或数据传递给子组件之前操纵它们”似乎正是我所需要的

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

提前感谢您的回答


up:在2018年3月7日,我仍然不知道如何解决这个问题

只要用定制的
制作一个常规组件即可

您需要为组件定义一个
items
道具,以便将其作为
组件的
items
传递

而且,要为组件定义
插槽
,需要使用
标记,使用
name
属性指定名称

如果您想在
组件中访问
组件中的一个插槽,只需在自定义组件中传递一个
标记作为插槽内容

它看起来像这样:

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 },
});
Vue.component('my-b-table'{
模板:`
要传递到b表插槽的内容
仅在此上下文中使用的插槽
将内容传递到b表组件插槽的插槽
`,
道具:{items:Array},
});

在那个月前,我找到了不知何故不清楚的答案

(“动态”在这里的意思是“不是由组件明确声明,而是由父级提供”)

包装组件 可以通过
createElement
函数的
options
对象动态地提供道具和作用域插槽

“简单”插槽可以通过
createElement
函数的
childs
数组动态分配

包裹组件 除非组件具有功能性,否则道具不能是动态的

插槽始终可以动态检索

仅当组件不起作用时,才能检索作用域插槽

结论 不可能同时拥有动态道具和范围插槽

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


如何 从非功能组件检索
var component=Vue.component('component-name'{
道具:['name','of','the','props'],
// [...]
方法:函数(){
这个。_props//所有声明的props
这是。$slots//所有插槽
这是。$scopedSlots//所有作用域插槽
}
});
从功能组件中检索
var component=Vue.component('component-name'{
功能性:对,
渲染:函数(createElement,上下文){
context.props//所有的道具
context.children//将所有插槽作为一个数组
context.slots()//将所有插槽作为一个对象
}
});
给予子组件
var component=Vue.component('component-name'{
渲染:函数(createElement){
返回createElement(
儿童部分,
{
道具:道具给予,
scopedSlots:scopedSlotsToGive
},
[
//要提供的非作用域插槽
createElement('slot-tag-name',{slot:'slot-name'})
]
);
}
});

工具书类


沙箱

遗憾的是,它并没有这么简单:使用b-table组件,您可以使用插槽以特定方式显示特定列。例如:如果您有一个名为“last_edit”的列,您可以使用这样的插槽:````因为它是一个“动态”插槽,所以我想将它们“提供”给b表子组件,我不确定我是否遵循。你是说你想让插槽也在你的
组件中?是的,我需要能够通过my-b-table为b-table分配一个槽位困难在于我不知道通过my-b-table组件的槽位名称,因为它们在每个用法中都会不同:
将内容传递到b-table组件槽位的槽位
可能图书页面会显示日期,文章页面将显示一个价格,两个“页面组件”都应该能够使用my-b-table,以避免显示复选框、ID和其他标识字段以及
<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>
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 },
});