Vue slot:默认插槽 具名插槽 作用域插槽

Vue 实现了一套内容分发的 API,将<slot>元素作为承载分发内容的出口,这是vue文档上的说明。具体来说,slot就是可以让你在组件内添加内容的‘空间’。总共分为三种:默认插槽 具名插槽 作用域插槽。

举一个例子说明插槽在父子组件间的作用:

将父组件的内容放到子组件指定的位置叫做内容分发,这就是slot插槽的作用,就是父组件引用子组件的同时,把父组件的内容放到子组件里面去。

比如我在子组件NavHeader中定义了一个slot标签,如下:

<div class="content">
    <slot></slot>  //子组件NavBread
</div>

父组件中的该组件(nav-bread)名称里直接写需要的内容:

<nav-bread>
  <span slot="bread">web秀</span>
</nav-bread>

这时候编译的代码就是这样的:

<div class="content">
  <span>web秀</span>
</div>

默认插槽举例

cartoonvue.vue

<div class="container">
	<categoryvue title="美食">
	  <img src="https://img1.baidu.com/it/u=3603349077,2543717877&fm=253&app=120&size=w931&n=0&f=PNG&fmt=auto?sec=1667754000&t=b6dde1b42b636e1c035c2b9af6c268b5">
	 </categoryvue>
	<categoryvue title="游戏">
	  <ul>
	    <li v-for="(g,index) in games" :key="index">{{g}}</li>
	  </ul>
	</categoryvue>
	<categoryvue title="电影">
	  <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
      </categoryvue>
    </div>

扩展 视频在浏览器上可以显示播放(controls 这个必须加不然视频没法播放)

<video controls  src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>

App.vue

 <!-- 默认插槽:单个slot -->
<template>
    <div class="categorystu">
      <h3>{{title}}</h3>
      <slot>默认插槽:我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
    </div>
</template>

      <!--组件数据交互-->
      <script>
        //这样写法更加简洁,这样用的多
        export default {
              //代表组件名称,最好与 school.vue中的school一致
              name:'categoryvue',
              props:['title']
          }
      </script>

      <!--组件样式-->
      <style>
        .categorystu{
          background-color: skyblue;
          width:200px;
          height: 300px;
        }
        h3{
            text-align: center;
            background-color: orange;
        }
        img{
          width: 100%;
        }
        video{
            width: 100%;
        }
      </style>

具名插槽举例:多个slot用name区别,App中相同name的不同数据都可以对应组件里面同一个<slot>标签

categoryvue2.vue

<!-- 具名插槽:多个slot用name区别 对应App.vue中name-->
<template>
    <div class="categorystu">
      <h3>{{title}}</h3>
      <slot name="zhong">具名插槽:我是一些默认值,当使用者没有传递具体结构时,我会出现zhong</slot>
      <slot name="dibu">具名插槽:我是一些默认值,当使用者没有传递具体结构时,我会出现dibu</slot>
    </div>
</template>

      <!--组件数据交互-->
      <script>
        //这样写法更加简洁,这样用的多
        export default {
              //代表组件名称,最好与 school.vue中的school一致
              name:'categoryvue2',
              props:['title']
          }
      </script>

      <!--组件样式-->
      <style>
        .categorystu{
          background-color: skyblue;
          width:200px;
          height: 300px;
        }
        h3{
            text-align: center;
            background-color: orange;
        }
        img{
          width: 100%;
        }
        video{
            width: 100%;
        }
        h4{
           text-align: center;
        }
      </style>

App.vue

<!--具名插槽-->
    <div class="container">
      <categoryvue2 title="美食">
        <img slot="zhong" src="https://img1.baidu.com/it/u=3603349077,2543717877&fm=253&app=120&size=w931&n=0&f=PNG&fmt=auto?sec=1667754000&t=b6dde1b42b636e1c035c2b9af6c268b5">
        <a slot="dibu" href="https://www.meituan.com/">更多美食</a>
      </categoryvue2>
      <categoryvue2 title="游戏">
        <ul slot="zhong">
          <li v-for="(g,index) in games" :key="index">{{g}}</li>
        </ul>
        <!--这里为了一个dibu模板slot显示两个,需要加空格样式,所以单独写一个div class中定义,直接在<a></a> 之间写<br>不起作用因为组件模板中没有定义,而且App里面直接<br>也失效带不到组件模板里面-->
        <div class="dibucss" slot="dibu">
          <a  href="https://code.51.com/jh/g51yx/i17/26ds5.html?g=bgjzqxc_1100145?rq=0&bd_vid=10419870625563131241">单机游戏1</a>
          <a  href="https://pvp.qq.com/">网络游戏2</a>
        </div>
      </categoryvue2>
      <categoryvue2 title="电影">
        <video slot="zhong" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
            <!--原本这是div,但是没必要生成,用template不生成最终的dom元素,省一层div结构-->
            <template slot="dibu">  <!--用template 也可以这样写 <template v-slot:dibu> 效果一样 但是div里面不行注意-->
            <div class="dibucss">
              <a  href="https://www.1905.com/">经典电影</a>
              <a  href="https://www.1905.com/">热门电影</a>
              <a  href="https://www.1905.com/">推荐电影</a>
            </div>
            <h4>欢迎来观看小悦悦</h4>
          </template>
      </categoryvue2>
    </div>

扩展 template标签:不生产具体的dom结果,用于替换div,写div也一样主要也没必要生成div。

作用域插槽举例:不像上面两个slot,这个是数据在子组件里面,通过slot中:cars获取数据,等App.vue把结构传到子组件后,自组件再把准备好的数据灌进结构里面,最后把带有数据的结构进行展示。

categoryvue3.vue

<!-- 作用域插槽-->
<template>
    <div class="categorystu">
      <h3>{{title}}</h3>
      <slot :cars="cars" msg="小悦悦你好啊!">作用域插槽:我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>
    </div>
</template>

      <!--组件数据交互-->
      <script>
        //这样写法更加简洁,这样用的多
        export default {
              //代表组件名称,最好与 school.vue中的school一致
              name:'categoryvue3',
              data(){
                  return{
                    cars:['法拉利','兰博基尼','奥迪','宝马'],
                  }
              },
              props:['title']
          }
      </script>

      <!--组件样式-->
      <style>
        .categorystu{
          background-color: skyblue;
          width:200px;
          height: 300px;
        }
        h3{
            text-align: center;
            background-color: orange;
        }
        img{
          width: 100%;
        }
        video{
            width: 100%;
        }
        h4{
           text-align: center;
        }
      </style>

App.vue

hahads => { "cars": [ "法拉利", "兰博基尼", "奥迪", "宝马" ] }
<div class="container">
      <!-- <categoryvue3 title="美食">
        <img src="https://img1.baidu.com/it/u=3603349077,2543717877&fm=253&app=120&size=w931&n=0&f=PNG&fmt=auto?sec=1667754000&t=b6dde1b42b636e1c035c2b9af6c268b5">
       </categoryvue3> -->
      <categoryvue3 title="汽车">
        <!--slot-scope 这里随便定义不需要对应  hahads就是categoryvue3中cars的具体数据-->
        <!--作用域插槽写法template必须写的!!-->
         <!--或者es6语法 直接slot-scope="cars" 然后下面直接in cars-->
        <template slot-scope="hahads">
          <!-- hahads => { "cars": [ "法拉利", "兰博基尼", "奥迪", "宝马" ] }-->
          <!--<ol> 有序 <ul>无序-->
          <ol>
            <!--cars具体数据在categoryvue3定义-->
            <li style="color:red" v-for="(c,index) in hahads.cars" :key="index">{{c}}</li>
          </ol>
          <!--获取组件里面msg="小悦悦你好啊!"的 小悦悦你好啊!-->
          <h4>{{hahads.msg}}</h4>
        </template>
      </categoryvue3>
      <!-- <categoryvue3 title="电影">
        <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
      </categoryvue3> -->
    </div>

注意:

  • 这里用作用域插槽那么<template slot-scope="hahads"> template是必须加的
  • <template slot-scope="hahads"> 可以用es6写法 <template slot-scope="{cars}"> 直接拿到cars里面数据。
  • 标签 <ol> 有序 <ul>无序
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值