VUE3.0,DAY57,插槽

插槽

案例分析

我们首先建立一个vue脚手架,修改App.vue,并自定义一个组件为category.vue,实现三个表单,如下所示。

<template>
  <div class="container">
    <Category title="美食" :listdata="foods"/>
    <Category title="游戏" :listdata="games"/>
    <Category title="电影" :listdata="films"/>
  </div>
</template>

<script>
import Category from "./components/Category.vue";
export default {
  name: "App",
  components: { Category },
  data() {
    return {
      foods:['吃饭','吃饭','吃饭'],
      games:['游戏','游戏','游戏'],
      films:['电影','电影','电影'],
    }
  },
};
</script>
<style>
.container {
  display: flex;
  /* 主轴对齐方式 */
  justify-content: space-around;
}
</style>


<template>
  <div class="category">
    <h1>{{ title }}</h1>
    <ul>
      <!-- 遍历App.vue传过来的参数listdata -->
      <li v-for="(item,index) in listdata" :key="index">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "Category",
  props: ['listdata', 'title'],
};
</script>

<style>
.category {
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h1 {
  text-align: center;
  background-color: orange;
}
</style>

在这里插入图片描述

默认插槽

现在,修改案例需求,要求美食表单中显示图片,电影表单中显示视频,游戏表单中不改变。我们使用的方法是把App.vue中的组件标签,写成有开始和结束标签的形式,然后在标签中间加上一些具体内容,在子组件Category中使用默认插槽<slot></slot>,指示vue将具体内容安插到slot内。

//App.vue代码
<template>
  <div class="container">
    <!-- 在组件标签的另一种写法中,即有开始和结束标签的写法,加入标签体内容 -->
    <Category title="美食">
      <img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="" />
    </Category>
    <Category title="游戏">
      <ul>
        <li v-for="(item, index) in games" :key="index">{{ item }}</li>
      </ul>
    </Category>
    <Category title="电影">
      <!-- controls是控制视频播放的属性 -->
      <video
        controls
        src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
      ></video>
    </Category>
  </div>
</template>

<script>
import Category from "./components/Category.vue";
export default {
  name: "App",
  components: { Category },
  data() {
    return {
      foods: ["吃饭", "吃饭", "吃饭"],
      games: ["游戏", "游戏", "游戏"],
      films: ["电影", "电影", "电影"],
    };
  },
};
</script>
<style scoped>
.container {
  display: flex;
  /* 主轴对齐方式 */
  justify-content: space-around;
}
video {
  width: 100%;
}
img {
  width: 100%;
}
</style>

//category.vue代码
<template>
  <div class="category">
    <h1>{{ title }}</h1>
    <!-- slot是插槽的意思,告诉vue,在App.vue中组件标签内的内容,放在此处 -->
    <slot>
      这里可以加一些默认值,当没有传递组件标签内的具体结构时,就会显示
      </slot
    >
    
  </div>
</template>

<script>
export default {
  name: "Category",
  props: [ "title"],
};
</script>

<style>
.category {
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h1 {
  text-align: center;
  background-color: orange;
}

</style>

在这里插入图片描述

具名插槽

具名插槽就是具有名字的插槽,当vue组件中出现多个插槽使用时,就得给每个插槽取个名字才可以避免混乱。在slot标签内增加name属性即可。具体使用如下:

//App.vue代码
<template>
  <div class="container">
    <!-- 在组件标签的另一种写法中,即有开始和结束标签的写法,加入标签体内容 -->
    <Category title="美食">
      <!-- 加上slot插槽名字,就告诉vue,该内容往叫center的插槽内放 -->
      <img
        slot="center"
        src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg"
        alt=""
      />
      <!-- 加上slot插槽名字,就告诉vue,该内容往叫footer的插槽内放 -->
      <a slot="footer" href="http://www.atguigu.com">更多美食</a>
    </Category>
    <Category title="游戏">
      <ul slot="center">
        <li v-for="(item, index) in games" :key="index">{{ item }}</li>
      </ul>
      <!-- 加上slot插槽名字,就告诉vue,该内容往叫footer的插槽内放 -->
      <a slot="footer" href="http://www.atguigu.com">单机游戏</a>
      <!-- 加上slot插槽名字,就告诉vue,该内容往叫footer的插槽内放 -->
      <a slot="footer" href="http://www.atguigu.com">网络游戏</a>
    </Category>
    <Category title="电影">
      <!-- controls是控制视频播放的属性 -->
      <video slot="center"
        controls
        src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
      ></video>
      <a slot="footer" href="http://www.atguigu.com">网络游戏</a>
      <a slot="footer" href="http://www.atguigu.com">网络游戏</a>
      <a slot="footer" href="http://www.atguigu.com">网络游戏</a>
    </Category>
  </div>
</template>

<script>
import Category from "./components/Category.vue";
export default {
  name: "App",
  components: { Category },
  data() {
    return {
      foods: ["吃饭", "吃饭", "吃饭"],
      games: ["游戏", "游戏", "游戏"],
      films: ["电影", "电影", "电影"],
    };
  },
};
</script>
<style scoped>
.container {
  display: flex;
  /* 主轴对齐方式 */
  justify-content: space-around;
}
video {
  width: 100%;
}
img {
  width: 100%;
}
</style>


//category.vue代码
<template>
  <div class="category">
    <h1>{{ title }}</h1>
    <!-- slot是插槽的意思,告诉vue,在App.vue中组件标签内的内容,放在此处 -->
    <!-- slot标签内的属性name是给插槽起名字 -->
    <slot name="center">
      这里可以加一些默认值,当没有传递组件标签内的具体结构时,就会显示
    </slot>
    <slot name="footer">
      这里可以加一些默认值,当没有传递组件标签内的具体结构时,就会显示
    </slot>
  </div>
</template>

<script>
export default {
  name: "Category",
  props: ["title"],
};
</script>

<style>
.category {
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h1 {
  text-align: center;
  background-color: orange;
}
</style>

最后输出效果如下:
在这里插入图片描述

作用域插槽

继续上边的例子,现在我们只保留游戏表单,页面显示三个游戏表单,在代码中,App.vue是组件category的使用者,数据也放在了App.vue中。现在提出新需求,对每个表单中的列表内容,显示不同,第一个是无序列表显示,第二个是有序列表显示,第三个变为h4标题显示。那么我们App.vue,即category的使用者怎么得到放在category组件内的数据呢?
App.vue代码

<template>
  <div class="container">
    <Category title="游戏">
      <!-- 要想拿到插槽反向传过来给插槽使用者的数据,就必须包裹上一个template -->
      <!-- v-slot是作用域的意思,等号后边的内容可以随便写,该内容接受反向传过来的数据,以对象的形式 -->
      <template v-slot:default="games">
        <ul>
          <li v-for="(item, index) in games.ShuJu" :key="index">{{ item }}</li>
        </ul>
      </template>
    </Category>
    <Category title="游戏">
      <template v-slot:default="games">
        <ol>
          <li v-for="(item, index) in games.ShuJu" :key="index">{{ item }}</li>
        </ol>
      </template>
    </Category>
    <Category title="游戏">
      <template v-slot:default="games">
        <h4 v-for="(item, index) in games.ShuJu" :key="index">{{ item }}</h4>
      </template>
    </Category>
  </div>
</template>

<script>
import Category from "./components/Category.vue";
export default {
  name: "App",
  components: { Category },
};
</script>
<style scoped>
.container {
  display: flex;
  /* 主轴对齐方式 */
  justify-content: space-around;
}
</style>


category中代码

<template>
  <div class="category">
    <h1>{{ title }}</h1>
    <!-- 这就是把data中的games数据传递给了插槽的使用者 -->
    <slot v-bind:ShuJu="games">
      这里可以加一些默认值,当没有传递组件标签内的具体结构时,就会显示
    </slot>
  </div>
</template>

<script>
export default {
  name: "Category",
  props: ["title"],
  data() {
    return {
      games: ["游戏", "游戏", "游戏"],
    };
  },
};
</script>

<style>
.category {
  background-color: skyblue;
  width: 200px;
  height: 300px;
}
h1 {
  text-align: center;
  background-color: orange;
}
</style>

实际输出效果
在这里插入图片描述

总结

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值