组件插槽

83 阅读2分钟

插槽

  • 作用: 用于给子组件传递内容
  • 分类: 默认插槽, 具名插槽, 作用域插槽
  • 写法:
    • 就是在组件标签内写html代码

默认插槽

image.png

父组件

<template>
  <Child>
    <h2>11111111</h2>
  </Child>
</template>

<script>
import Child from "./Child.vue";
export default {
  components: {
    Child,
  },
};
</script>

子组件

<template>
    <div>
        child
        <slot></slot>
    </div>
</template>

结果

image.png

具名插槽

image.png

  1. 在子组件中,定义插槽
  2. 在父组件中,使用子组件标签,在标签中使用slot属性,值为子组件中定义的插槽名称
    • v-solt="子组件中定义的插槽名称" 简写 #子组件中定义的插槽名称 父组件
<template>
  <div>
    <Child>
      <template v-slot:left>
        <div>返回</div>
      </template>
      <template #right>
        <div>搜索</div>
      </template>
      <template v-slot:title>
        <div>我是标题</div>
      </template>
    </Child>
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  components: {
    Child,
  },
};
</script>

子组件

<template>
  <div class="header">
    <div class="left">
      <slot name="left"></slot>
    </div>
    <div class="title">
      <slot name="title"></slot>
    </div>
    <div class="right">
      <slot name="right"></slot>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.header {display: flex;justify-content: space-between;padding: 0px 10px;height: 50px;background: wheat;align-items: center;text-align: center;
.title {flex: 1;margin: 0px 10px;}
}
</style>

image.png

作用域插槽

image.png

  • 插槽的slot标签中可以写默认的值 -如果父组件没有使用这个插槽,则使用默认的值
  • 在作用域插槽中,
    • 向父组件传递信息用 :名字1="要传递的数据1" :名字2="要传递的数据2"
    • 在父组件中,接收信息使用 #default="scope" scope可以是任意字符,这里的scope是一个对象,
    • 使用数据 scope.名字1 scope.名字2
  • 【注】
    • #default是默认的,如果插槽有name属性,那么就不能使用#default接受了,
    • 而是使用 #name的值="scope"

父组件

<template>
  <Child>
    <!-- 作用域插槽 -->
    <!-- 由于子组件的插槽没有定义name,所以这里使用default默认作用域插槽 -->
    <template #default="scope">
      <h2>{{ scope.title }}</h2>
      <li v-for="data in scope.mydata" :key="data.filmId">
        <img :src="data.poster" alt="" style="width: 100px" />
        {{ data.name }}
      </li>
    </template>

    <!-- 具名插槽 + 作用域插槽 -->
    <!-- conHot是子组件中定义的插槽名字 -->
    <!-- <template #conHot="scope">  
      <h2>{{ scope.title }}</h2>
      <li v-for="data in scope.mydata" :key="data.filmId">
        <img :src="data.poster" alt="" style="width: 100px" />
        {{ data.name }}
      </li>
    </template> -->
  </Child>
</template>

<script>
import Child from "./Child.vue";
export default {
  conponents: {
    Child,
  },
  components: { Child },
};
</script>

<style scoped lang="scss">
h2 {
  text-align: center;
}
</style>

子组件

<template>
  <ul>
    <!-- 作用域插槽 -->
    <slot :mydata="dataList" :title="'热门电影'">
      <li v-for="data in dataList" :key="data.filmId">
        {{ data.name }}
      </li>
    </slot>

    <!-- 具名插槽 + 作用域插槽 -->
    <!-- <slot name="conHot" :mydata="dataList" :title="'热门电影'">
      <li v-for="data in dataList" :key="data.filmId">
        {{ data.name }}
      </li>
    </slot> -->
  </ul>
</template>

<script>
import axios from "axios";
export default {
  data() {
    return {
      dataList: [],
    };
  },
  //   生命周期函数 -- 当组件被创建时,自动执行
  created() {
    axios.get("/public/database/hotFilms.json").then((res) => {
      console.log(res.data.data.films);
      this.dataList = res.data.data.films;
    });
  },
};
</script>

<style>
li {
  padding: 10px 0;
  display: flex;
  align-items: center;
}
</style>