如何将每个元素包装在一个插槽中?

时间:2017-07-07 09:04:25

标签: vue.js vuejs2

我编写了一个组件(组件B),它通过插槽接受自定义组件列表,如此

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

我希望将组件x和y包装在其他组件中,例如li tag。

// 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对象,无法使用组件标记进行渲染。有没有解决这个问题的解决方案?

编辑:我的包装组件不是li标签,它是一个带有指定道具的自定义组件,我在组件B中设置它。如果我从组件A中包装它们,我需要重复编写自定义组件及其道具

Edit2:渲染功能可能解决了这个问题,但我正在寻找带有html模板的解决方案(单个文件组件)。

2 个答案:

答案 0 :(得分:2)

我想如果没有成人版本(render function),就无法做到这一点。

PS:对于更详细的组件,没有乱七八糟的渲染功能,我建议插入另一个组件来处理其他功能,例如:

createElement(componentForMakeCoolThings,{props...})    

PS2:您可以在单个文件组件中使用以下解决方案,并进行简单的调整:

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

&#13;
&#13;
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'});
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这有效吗?

<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>