将类绑定到Vue.js中的插槽2

时间:2017-02-08 13:14:20

标签: javascript vue.js vuejs2

我试图创建一个可重用的组件来迭代项目,过滤它们,并向插槽中添加一些类(如果项目是偶数,奇数,第一个,最后一个等等。)

这是我的可重用组件:

<template>
  <ul :class="classes">
    <slot
      v-for="(item, index) in filteredItems"
      :item="item"
      :class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </slot>
  </ul>
</template>

<script>
export default {
  props: ['items', 'classes'],
  data() {
    return {
      filteredItems: this.items.filter(item => item.active)
    };
  }
};
</script>

以下是我如何使用它:

<component-list :classes="'some-class'" :items="category.products">
  <template scope="props">
    <product :product="props.item"></product>
  </template>
<component-list>

一切都按预期工作,但它没有为放入的元素添加类。

我做错了吗?在Vue.js 2中技术上是否可以做这样的事情?

感谢您提供任何帮助或建议!

3 个答案:

答案 0 :(得分:9)

来自广告位的vuejs2样式已被删除,如here所述:

  

通过named插入的内容不再保留slot属性。使用包装器元素对其进行样式化,或者对于高级用例,使用呈现函数以编程方式修改插入的内容。

建议的最简单的方法是使用如下的包装元素:

<template>
  <ul :class="classes">
    <slot>
      <div
      v-for="(item, index) in filteredItems"
      :item="item"
      :class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </div>
    </slot>
  </ul>
</template>

答案 1 :(得分:1)

我有另一种方式可以实现您的目标,但不能使用render,仍然使用slot

可重复使用的组件:

<template>
  <ul :class="classes">
    <slot
      v-for="(item, index) in filteredItems"
      :item="item"
      :_class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </slot>
  </ul>
</template>

<script>
export default {
  props: ['items', 'classes'],
  data() {
    return {
      filteredItems: this.items.filter(item => item.active)
    };
  }
};
</script>

使用_classclass关键字,因此Vue.js会将_class作为公共属性。

然后在你的使用中:

<component-list :classes="'some-class'" :items="category.products">
  <template scope="{ item, _class }">
    <product :product="item" :class="_class"></product>
  </template>
<component-list>

通过范围属性,您仍然可以从广告位获得_class

毕竟,使用render可能更简洁。 :)

答案 2 :(得分:0)

在您的子组件中,请勿使用插槽标记,只需将插槽数据绑定到普通元素即可。

例如说我有一个叫做模态的组件。在我的父母,我有这个:

<modal>
    <h1 slot="title">My modal title</h1>
</modal>

因此,使用普通插槽时,我的子组件将具有以下标记:

<slot name="title" class="this-class-will-not-get-added"></slot>

但是这个课程不会被添加。

所以我们可以这样做:

<h1 class="this-class-will-get-added">{{this.$slots.title['0'].children['0'].text}}</h1>