为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

牧羊人nacy 2023-09-28 17:39:05
我正在尝试从渲染函数构建自定义组件。正在渲染的该组件接受任意数量的槽。在下面的示例中,有三个可用插槽(名为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') }}), {})  });},然而没有任何渲染,也没有错误来指导我。有任何想法吗?
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

不同之处在于,在您的 中reduce,您创建的函数为

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

在您的硬编码版本中(也在forEach@Boussadjra的答案中的循环中),它们被创建为

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

这实际上是return创建的元素。这与使用无关reduce,这很好。

const ReplicatorComponent = {

  template: `<div>

    <h1>replicator-component</h1>

    <slot name='element_1'></slot>

    <slot name='element_2'></slot>

    <slot name='element_3'></slot>

  </div>`

};


const records = [

  { "index": 1 },

  { "index": 2 },

  { "index": 3 },

];


Vue.component('my-component', {

  render: function(createElement) {

    return createElement(ReplicatorComponent, {

      attrs: {

        elements: records.length

      },

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

        ...a, 

        ['element_' + x.index]: () => 

          createElement( 'div', 'hello world')

       }), {})

    });

  },

});


new Vue({

  el: '#app',

  data: () => ({})

});

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>


<div id="app">

  <my-component></my-component>

</div>


查看完整回答
反对 回复 2023-09-28
?
catspeake

TA贡献1111条经验 获得超0个赞

该reduce方法不起作用,因为它之前缺少返回createElement('div', 'hello world'):


完整示例


const ReplicatorComponent = {


  template: `

 <div>

    <h1>replicator-component</h1>

    

    <slot name='element_1'></slot>

    <slot name='element_2'></slot>

    <slot name='element_3'></slot>

 </div>

`

}


const records = [{

    "index": 1,

  },

  {

    "index": 2,

  },

  {

    "index": 3,

  }

]




Vue.component('my-component', {

  render: function(createElement) {


    let slotContent = records.reduce((a, x) => ({ ...a,

      ['element_' + x.index]:

        () => {

        return  createElement('div', 'hello world')

        }

    }), {})

    return createElement(ReplicatorComponent, {

      attrs: {

        elements: records.length

      },

      scopedSlots: slotContent

    });

  },

})


var app = new Vue({

  el: '#app',


  data: () => ({})

})

<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>


<div id="app">

  test


  <my-component></my-component>

</div>


查看完整回答
反对 回复 2023-09-28
?
aluckdog

TA贡献1847条经验 获得超7个赞

我认为作用域插槽应该是props根据 Vue.js 文档作为参数的函数


export default {

  render(createElement) {

 

    // ...

    // some other stuff

    // ...


    // Scoped slots in the form of

    // { name: props => VNode | Array<VNode> }

    scopedSlots: {

      default: props => createElement('span', props.text)

    },

  }

}


所以也许你应该尝试一下


v-slot你也可以使用 vue 的新统一系统完成同样的事情


<!-- page component -->

<template>

  <some-component>

    <template v-for="slot in scopedSlots" v-slot:[slot]="props">

      hello {{props}}

    </template>

  </some-component>

</template>


<!-- some-component.vue -->


<template>

  <div>

    <slot v-for="slot in Object.keys($slots)" :name="slot"></slot>

  </div>

</template>


查看完整回答
反对 回复 2023-09-28
  • 3 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信