您的位置:

作用域插槽的使用和应用场景

一、作用域插槽使用方法

作用域插槽是在父组件上定义一个插槽,并且在该插槽内部的内容中,可以访问子组件的数据和方法。子组件利用v-bind指令来绑定父组件中的数据或传递方法。

<!-- 父组件 -->
<parent>
  <template v-slot:default>
    <child>
      <template v-slot:slotName="slotProps">
      </template>
    </child>
  </template>
</parent>

<!-- 子组件 -->
<child>
  <template v-slot:slotName="slotProps">
    <div>{{ slotProps.data }}</div>
  </template>
</child>

在父组件中,通过v-slot:default为子组件指定了一个插槽名称。在子组件中,通过v-slot:slotName来指定它为父组件中指定的插槽。在v-slot:slotName中,我们可以通过传递slotProps来获取父组件中的数据,其中slotProps是一个对象,包含所需数据的属性。

二、作用域插槽和具名插槽能一起用吗?

是的,可以。具名插槽和作用域插槽是可以同时存在的。可以将具名插槽和作用域插槽一起使用,做到更细粒度的控制。

<!-- 父组件 -->
<parent>
  <template v-slot:default>
    <child>
      <template v-slot:header>
        <h1>{{ title }}</h1>
      </template>
      <template v-slot:body="slotProps">
        <p>{{ slotProps.articleContent }}</p>
      </template>
    </child>
  </template>
</parent>

<!-- 子组件 -->
<child>
  <slot name="header"></slot>
  <template v-slot:body="slotProps">
    <div>{{ slotProps.data }}</div>
  </template>
</child>

在父组件中,我们为child组件指定了两个具名插槽:header和body。其中header不传递数据,仅用于渲染标题。body通过作用域插槽传递数据给子组件。在子组件中,我们对header进行了直接渲染,对body组件通过v-slot指令获取了父组件中传递的数据。

三、作用域插槽如何传值

在父组件中,当为作用域插槽指定名称时,可以通过传递一个包含所需数据的对象来向子组件传递数据。

<!-- 父组件 -->
<parent>
  <template v-slot:default="slotProps">
    <child :title="slotProps.title"></child>
  </template>
</parent>

<!-- 子组件 -->
<child>
  <h1>{{ title }}</h1> 
</child>

在父组件中,我们通过v-slot指令指定了作用域插槽default,并通过传递一个包含所需数据的对象来向子组件传递数据。在子组件中,我们通过props接收父组件传递的数据。

四、作用域插槽多个数据

如果需要在作用域插槽中传递多个数据,则可以使用一个对象字面量来传递多个属性。

<!-- 父组件 -->
<parent>
  <template v-slot:default="slotProps">
    <child :title="slotProps.title" :content="slotProps.content"></child>
  </template>
</parent>

<!-- 子组件 -->
<child>
  <h1>{{ title }}</h1> 
  <p>{{ content }}</p>
</child>

在父组件中,我们通过v-slot指令指定了作用域插槽default,并通过传递一个包含所需数据的对象来向子组件传递数据。在子组件中,我们通过props接收父组件传递的数据。

五、作用域插槽的使用

在组件中使用作用域插槽可以将组件的数据暴露给父组件,父组件可以对这个数据进行操作,组件内的数据状态不会改变。

举个例子,在一个列表页中,我们可能有多个列表项,列表项可以根据传入的数据进行渲染。在某些情况下,父组件需要对列表项的展示进行一些操作,比如分页、筛选等。这时候可以使用作用域插槽,将列表项的数据暴露给父组件进行操作。如下:

<!-- 父组件 -->
<template>
  <div>
    <my-list :list-data="listData">
      <template v-slot:list-item="slotProps">
        <div>{{ slotProps.itemData }}</div>
        <div v-if="slotProps.itemData.visible">可以展示</div>
      </template>
    </my-list>
    <button @click="handleFilter">筛选</button>
  </div>
</template>

<script>
import MyList from './MyList.vue';

export default {
  components: {
    MyList,
  },
  data() {
    return {
      listData: [
        { id: 1, name: 'item1', visible: true },
        { id: 2, name: 'item2', visible: false },
        { id: 3, name: 'item3', visible: true },
        { id: 4, name: 'item4', visible: false },
        { id: 5, name: 'item5', visible: true },
      ],
    };
  },
  methods: {
    handleFilter() {
      this.listData.forEach((item) => {
        item.visible = !item.visible;
      });
    },
  },
};
</script>

<!-- 子组件 -->
<template>
  <div>
    <ul>
      <li v-for="item in listData" :key="item.id">
        <slot name="list-item" :itemData="item"></slot>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  props: {
    listData: {
      type: Array,
      default: () => [],
    },
  },
};
</script>

在父组件中,我们定义了一个名为list-item的作用域插槽,将列表项的数据暴露给父组件,父组件可以通过访问slotProps.itemData来获取列表项的数据。在父组件的按钮点击事件中,我们通过操作父组件的listData中每个item的visible属性来控制列表项的展示与否。

六、vue作用域插槽

作用域插槽是Vue中高级别的插槽技术之一。Vue的另一个插槽技术是具名插槽。作用域插槽可以通过将子组件中的数据暴露给父组件,为组件提供更高额外的数据灵活性。

七、vue作用域插槽使用场景

使用场景:

  • 当上层组件需要在数据上处理某些逻辑时,可以使用作用域插槽将某个数据传递到上层组件中;
  • 当上层组件需要对子组件的某些内容进行自定义展示时,可以使用具名插槽和作用域插槽相结合,实现更细粒度的控制。
  • 适用于列表和表单等组件,让组合性更清晰。

八、作用域插槽和普通插槽的区别

普通插槽是不具备传递数据的能力的,而作用域插槽可以通过指定一个slotProps对象来传递数据。作用域插槽还可以指定名称,从而区分多个插槽。

九、作用域插槽快捷方式

Vue 2.6.0+ 中添加了一个缩写语法,用于将所有 prop 作为作用域插槽的参数传递给子组件。

<!-- 父组件 -->
<parent>
  <template v-slot:default="slotProps">
    <child v-bind="slotProps"></child>
  </template>
</parent>

在上面的例子中,我们使用v-bind指令将父组件的所有prop传递给子组件。子组件中不再需要接收prop,作用域插槽中可以直接访问这些值。

十、总结

作用域插槽是Vue中高级别的插槽技术之一,可以将子组件的数据暴露给父组件进行操作,同时也具有名称、传递多个数据等优点。通过作用域插槽的使用,可以实现更加细致的组件间数据传递和交互。