vue.js 如何将每个元素封装到插槽中?

nc1teljy  于 2023-11-21  发布在  Vue.js
关注(0)|答案(3)|浏览(132)

我编写了一个组件(组件B),它通过插槽接受定制组件列表,如下所示

// Component A
<div class="component-a">
  ...
  <component-b>
    <component-x></component-x>
    <component-y></component-y>
  </component-b>
  ...
</div>

字符串
我想把x和y两个分量 Package 在另一个分量里,比如li标签。

// Output
...
<ul>
  <li><component-x></component-x></li>
  <li><component-y></component-y></li>
</ul>
...


我尝试与

// Component B
<div class="component-b">
  <ul>
    <li v-for="item in $slots.default">
      <component :is="item"></component>
    </li>
  </ul>
</div>


无法工作。项目是VNode对象,无法使用组件标记渲染。有什么解决方案可以解决这个问题吗?
编辑:我的 Package 组件不是li标签,它是一个自定义组件,我在组件B中设置了指定的props。如果我从组件A Package 它们,我需要重复编写自定义组件及其props。
Edit2:渲染功能可能解决这个问题,但我正在寻找解决方案与html模板(单文件组件)。

3df52oht

3df52oht1#

我想这是不可能的,没有成人版(render function)。
PS:对于一个更详细的组件,而不与渲染功能混乱,我建议插入另一个组件来处理其他功能,例如:

createElement(componentForMakeCoolThings,{props...})

字符串
PS2:你可以使用下面的解决方案在一个简单的适应单一文件组件:

<script>
  export default{
     render: function(createElement){
     }
  }
</script>

Vue.component('makeLi',{
  render:function(createElement){
        var list = []
        this.$slots.default.forEach((element,index) => {
            if(element.tag){
                list.push(createElement('li',{},[element]))
                
            }
        });

        return createElement('ul',{},list)
    }

})

new Vue({el:'#app'});
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="app">
<make-li>
 <h1>test1</h1>
 <b>bold</b>
 <i>italic</i>
</make-li>

</div>

的字符串

tyu7yeag

tyu7yeag2#

这能用吗

<div class="component-a">
  <component-b>
    <component-x></component-x>
    <component-y></component-y>
  </component-b>
</div>

字符串
然后使用

<div class="component-a">
  <component-b>
    <ul>
      <li><component-x></component-x></li>
      <li><component-y></component-y></li>
    </ul>
  </component-b>
</div>

sg2wtvxw

sg2wtvxw3#

我一直在寻找一个完全相同的问题的解决方案,最终遇到了这篇博客文章,它为我解决了Vue 2 https://www.jankollars.com/posts/vue-2-wrapping-slot-items/
我在文章中使用了最终的解决方案,为了完整起见,我将在这里添加:
我有一个父组件,其中包含一个按钮列表组件。按钮列表需要通过插槽接收一些项目,它需要 Package 在一个单独的li标签中的每个项目
在按钮列表组件中,我添加了一个components部分,它定义了一个VNodes组件(如果您愿意,可以将其作为单独的组件构建在自己的文件中)

components: {
    /**
     * Allows us to individually render each element passed to the default slot
     * Useful so that we can wrap them in other elements
     */
    VNodes: {
      functional: true,
      render: (h, ctx) => ctx.props.vnodes
    }
  }

字符串
在按钮列表组件的模板中,

<template>
  <ul class="button-list">
    <li
      v-for="(item, i) in $slots.default" :key="i"
      class="button-list__item"
    >
      <v-nodes :vnodes="item" />
    </li>
  </ul>
</template>


注意,我没有在模板中显式声明<slot>-我不确定如何使用命名插槽来实现这一点,但这可能是可能的
然后我的父组件使用button-list,并传递给它一些项(在我的例子中是另一个组件,但您可以在这里传递任何您需要的东西)

<button-list class="m-button-list--padded">
            <menu-button
                v-for="button in buttons"
                :href="button.href"
                :label="button.label"
            />
          </button-list>


什么是输出

<template>
  <ul class="button-list">
    <li class="button-list__item">
      < A Button />
    </li>
    <li class="button-list__item">
      < A Button />
    </li>
  </ul>
</template>


我认为这正是最初的海报试图实现的-希望这有助于处于类似困境的人!

相关问题