大家好,请原谅我的英语:-)
我有一个可以采用动态槽的 Vue 组件(槽的名称取决于 props)。
我在多个地方使用它,并且某些插槽始终存在。
为了避免冗余,我正在寻找一种方法来创建一个“包装”最终组件的组件,以允许我仅定义附加插槽。
如果有一种“明显”的方法来实现它,我可能会错过它:-)
代码示例
没有“包装组件”
<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那:
They’re (the functionnal components) also very useful as wrapper components. For example, when you need to:
- Programmatically choose one of several other components to delegate to
- Manipulate children, props, or data before passing them on to a child component
“在将子组件、 Prop 或数据传递给子组件之前对其进行操作”似乎正是我所需要的。
我查看了渲染函数,但很多东西似乎都没有实现,比如 v-model,而且我很难弄清楚如何传递动态槽...
提前感谢您的回答!
up:2018年3月7日我仍然不知道如何解决这个案例
最佳答案
找到了一个月前我不太清楚的答案。
(“动态”在这里意味着“不是由组件显式声明,而是由父组件给出”)
包装组件
Props 和作用域槽可以通过 createElement
函数的 options
对象动态给出。
“简单”槽可以通过 createElement
函数的 childs
数组动态给出。
包装组件
除非组件具有功能,否则 Prop 不能是动态的。
插槽始终可以动态检索。
仅当组件不起作用时才能检索作用域插槽。
结论
不可能同时拥有动态 Prop 和作用域插槽...
但是可以声明所有需要的 Prop ,然后使用“非功能”组件作为包装器和包装。
如何
从非功能组件中检索
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
},
[
// non-scoped slots to give
createElement('slot-tag-name', {slot: 'slot-name'})
]
);
}
});
引用文献
https://v2.vuejs.org/v2/guide/render-function.html
https://v2.vuejs.org/v2/guide/render-function.html#createElement-Arguments
https://v2.vuejs.org/v2/guide/render-function.html#Functional-Components
沙盒
关于vue.js - 如何封装/包装 VueJS 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48807290/