在 Render 函数中构建动态数量的 Vue 插槽

我正在尝试从渲染函数构建自定义组件。


正在渲染的该组件接受任意数量的槽。在下面的示例中,有三个可用插槽(名为element_1、element_2、element_3)。


以下内容Array.reduce()相当于:


scopedSlots: {

  "element_1": () => createElement('div', 'hello world'),

  "element_2": () => createElement('div', 'hello world'),

  "element_3": () => createElement('div', 'hello world'),

}

这是一个精简的示例Array.reduce():


const records = [

  {

    "index": 1,

  },

  {

    "index": 2,

  },

  {

    "index": 3,

  }

]


render: function (createElement) {

  return createElement("replicator-component", {

    attrs: { elements: records.length},


    scopedSlots: records.reduce((a,x) => ({...a, 

      ['element_' + x.index]: 

      () => { createElement( 'div', 'hello world') }}), {})

  });

},

然而没有任何渲染,也没有错误来指导我。有任何想法吗?


牧羊人nacy
浏览 124回答 3
3回答

蝴蝶刀刀

不同之处在于,在您的 中reduce,您创建的函数为()&nbsp;=>&nbsp;{&nbsp;createElement(&nbsp;'div',&nbsp;'hello&nbsp;world')&nbsp;}在您的硬编码版本中(也在forEach@Boussadjra的答案中的循环中),它们被创建为()&nbsp;=>&nbsp;createElement('div',&nbsp;'hello&nbsp;world')这实际上是return创建的元素。这与使用无关reduce,这很好。const ReplicatorComponent = {&nbsp; template: `<div>&nbsp; &nbsp; <h1>replicator-component</h1>&nbsp; &nbsp; <slot name='element_1'></slot>&nbsp; &nbsp; <slot name='element_2'></slot>&nbsp; &nbsp; <slot name='element_3'></slot>&nbsp; </div>`};const records = [&nbsp; { "index": 1 },&nbsp; { "index": 2 },&nbsp; { "index": 3 },];Vue.component('my-component', {&nbsp; render: function(createElement) {&nbsp; &nbsp; return createElement(ReplicatorComponent, {&nbsp; &nbsp; &nbsp; attrs: {&nbsp; &nbsp; &nbsp; &nbsp; elements: records.length&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; scopedSlots: records.reduce((a,x) => ({&nbsp; &nbsp; &nbsp; &nbsp; ...a,&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ['element_' + x.index]: () =>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createElement( 'div', 'hello world')&nbsp; &nbsp; &nbsp; &nbsp;}), {})&nbsp; &nbsp; });&nbsp; },});new Vue({&nbsp; el: '#app',&nbsp; data: () => ({})});<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script><div id="app">&nbsp; <my-component></my-component></div>

catspeake

该reduce方法不起作用,因为它之前缺少返回createElement('div', 'hello world'):完整示例const ReplicatorComponent = {&nbsp; template: `&nbsp;<div>&nbsp; &nbsp; <h1>replicator-component</h1>&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; <slot name='element_1'></slot>&nbsp; &nbsp; <slot name='element_2'></slot>&nbsp; &nbsp; <slot name='element_3'></slot>&nbsp;</div>`}const records = [{&nbsp; &nbsp; "index": 1,&nbsp; },&nbsp; {&nbsp; &nbsp; "index": 2,&nbsp; },&nbsp; {&nbsp; &nbsp; "index": 3,&nbsp; }]Vue.component('my-component', {&nbsp; render: function(createElement) {&nbsp; &nbsp; let slotContent = records.reduce((a, x) => ({ ...a,&nbsp; &nbsp; &nbsp; ['element_' + x.index]:&nbsp; &nbsp; &nbsp; &nbsp; () => {&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; createElement('div', 'hello world')&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }), {})&nbsp; &nbsp; return createElement(ReplicatorComponent, {&nbsp; &nbsp; &nbsp; attrs: {&nbsp; &nbsp; &nbsp; &nbsp; elements: records.length&nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; scopedSlots: slotContent&nbsp; &nbsp; });&nbsp; },})var app = new Vue({&nbsp; el: '#app',&nbsp; data: () => ({})})<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script><div id="app">&nbsp; test&nbsp; <my-component></my-component></div>

aluckdog

我认为作用域插槽应该是props根据 Vue.js 文档作为参数的函数export default {&nbsp; render(createElement) {&nbsp;&nbsp; &nbsp; // ...&nbsp; &nbsp; // some other stuff&nbsp; &nbsp; // ...&nbsp; &nbsp; // Scoped slots in the form of&nbsp; &nbsp; // { name: props => VNode | Array<VNode> }&nbsp; &nbsp; scopedSlots: {&nbsp; &nbsp; &nbsp; default: props => createElement('span', props.text)&nbsp; &nbsp; },&nbsp; }}所以也许你应该尝试一下v-slot你也可以使用 vue 的新统一系统完成同样的事情<!-- page component --><template>&nbsp; <some-component>&nbsp; &nbsp; <template v-for="slot in scopedSlots" v-slot:[slot]="props">&nbsp; &nbsp; &nbsp; hello {{props}}&nbsp; &nbsp; </template>&nbsp; </some-component></template><!-- some-component.vue --><template>&nbsp; <div>&nbsp; &nbsp; <slot v-for="slot in Object.keys($slots)" :name="slot"></slot>&nbsp; </div></template>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript