关于Vue中的插槽

插槽概述

Vue中提供了一种语法:插槽slot,可以在一个网页视图中预留数据位置
Vue中针对视图中占用位置和数据传递方式的不同,区分为:

  • 匿名插槽
  • 具名插槽
  • 作用域插槽
匿名插槽

匿名插槽主要用来封装通用视图,如果视图中只有一个位置的数据不一致 ,就可以通过 <slot></slot> 预留一个插槽位置,父组件在使用子组件时就可以给插槽位置添加自定义数据
子组件

<template>
 <div class="box-list">
    <h2>自定义标题 - 展示列表数据</h2>
    <!-- 不一致的数据展示部分,预留插槽:让父组件使用子组件传递视图数据 -
->
    <!-- slot标签没有name属性,所以称为 匿名插槽-->
    <slot> 默认的视图数据(父组件如果没有传递视图数据就展示默认视图)
</slot>
  </div>
</template>

父组件

<template>
  <div id="app">
    <h2>入口模块</h2>
    <h4>1、匿名插槽的使用</h4>
    <!-- 开始标签和结束标签中没有传递视图数据-->
    <SlotComp01></SlotComp01>
    <hr>
    <SlotComp01>
      <!-- 开始标签和结束标签中,添加内容:默认占用插槽的位置-->
      <ul>
        <li>不信谣、不传谣,半夜偷偷焊铁条</li>
        <li>抗疫~ 静默不能代替管控</li>
      </ul>
    </SlotComp01>
    <hr>
   </div>
</template>
<script>
// 导入
import SlotComp01 from "./pages/SlotComp01"
  
export default {
  components: {
    // 注册
    SlotComp01
 }
}
</script>
具名插槽

封装的子组件中,视图结构一致,但是多个位置的数据可能不一致,需要在子组件中预留多个可以插入数据的位置,就需要用到具名插槽(命名插槽)
子组件

<tempate>
 <div class="box-msg">
    <!-- name="title"的具名插槽位置-->
    <h2> <slot name="title">默认标题位置</slot></h2>
    
    <!-- 匿名插槽位置-->
    <p> <slot> 默认内容位置</slot> </p>
    
    <div>
    <!-- name="footer"的具名插槽位置-->
      <slot name="footer"> 默认注意事项位置 </slot>
    </div>
  </div>
</tempate>

父组件

<template>
 <div id="app">
    <h4>2、具名插槽的使用</h4>
    <div class="content">
      <!-- 直接使用,不注入内容 -->
      <SlotComp02></SlotComp02>
      <!-- 给指定名称的插槽,添加内容 -->
      <SlotComp02>
        <!-- 给name="title"的插槽添加数据 -->
        <template slot="title">
         自定义标题
        </template>
        <!-- 给匿名插槽添加数据 -->
        <span>自定义内容
</span>
        <!-- 给name="footer"的插槽添加数据-->
        <template slot="footer">
          <span>自定义页脚</span>
        </template>
      </SlotComp02>
      <!-- 给指定名称的插槽,添加内容 -->
      <SlotComp02>
        <!-- 给name="title"位置添加标题 : 简化语法-->
        <template #title>
         具名插槽简化
        </template>
        <!-- 给匿名插槽添加数据 -->
        <p>给name="title"位置添加标题简化语法:#title</p>
        <!-- 给name="footer"添加数据-->
        <template #footer>
         页脚内容
        </template>
      </SlotComp02>
    </div>
      </div>
</template>
<script>
import SlotComp02 from "./pages/SlotComp02"
  
export default {
  components: {
    SlotComp02
 }
}
</script>
作用域插槽

父组件传递给子组件进行数据管理,匿名插槽/具名插槽都是数据的展示/查询,如果在子组件中需要修改数据时,如果将要改动的数据传递给父组
件,让父组件完成数据的改动,就需要使用到插槽。

子组件

<template>
 <div class="box-table">
    <table>
	   <tr>
			<th>序号</th>
	        <th>名称</th>
	        <th>操作</th>
	   </tr>  
      <tr v-for="goods in goodsList" :key="goods.id">
 		<td>{{goods.id}}</td>
        <td>{{goods.name}}</td>
        <td>
		 <!-- 预留插槽:操作数据的方式可能不一致-->
		 <!-- 给插槽添加自定义属性,将数据通过属性传递给父组件 {row:
		商品对象}-->
          <slot :row="goods"></slot>
 		</td>
	 </tr>
 	</table>
 </div>
</template>
<script>
export default {
  // 声明自定义属性接收父组件数据
  props: ['goodsList']
}
</script>

父组件

<template>
 <div id="app">
    <h3>展示商品数据</h3>
    <SlotComp03 :goods-list="goodsList">
      <!-- 通过v-slot指令接收插槽传递的属性数据 props: {row:商品对
象}-->
 <template v-slot="props">
 <button @click="check(props)">查看数据</button>
 </template>
 </SlotComp03>
 <SlotComp03 :goods-list="goodsList">
      <!-- 通过v-slot指令接收插槽传递的属性数据 props: {row:商品对
象}-->
 <template v-slot="props">
 <button @click="edit(props)">编辑</button>
 <button @click="del(props)">删除</button>
 </template>
 </SlotComp03>
  </div>
</template>
<script>
import SlotComp03 from "./pages/SlotComp03"
export default {
  components: {
    SlotComp03
 },
  data() {
    return {
      goodsList: [ // 商品数据
       {id: 2, name: "华为"},
       {id: 1, name: "小米"}
     ]
   }
 },
  methods: {
	 check(props){
	      console.log("查看商品对象:", props.row)
	   },
	   edit(props){
	      console.log("编辑的商品:", props.row)
	   },
	    del(props){
	      console.log("准备删除:", props.row)
	   }
  }
}
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值