2021-08-06 vue笔记-插槽:匿名插槽,具名插槽和作用域插槽的定义和使用,在vue项目中使用插槽

本文介绍了Vue中的插槽,包括什么是插槽、插槽的作用,以及三种类型的插槽:匿名插槽、具名插槽和作用域插槽的定义与使用方法,通过示例详细解析了它们在网页和Vue项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,介绍插槽

1.什么是插槽?
理解

插槽就是在子组件中用<slot></slot>挖个坑,坑内内容由父组件来决定

子组件提供给父组件使用一个占位符slot,
父组件可在slot中填充任何模板代码,如 HTML、组件等,
填充的内容会替换子组件中的<slot></slot>标签。
作用

提高组件的重用能力

步骤

子组件:在指定位置留下<slot></slot>
父组件:引入,注册子组件,在子组件的同名占位符中写东西(如 HTML、组件等)

区分父子组件

(*换言之:使用了<slot></slot>或者<slot name-"xxx"></slot>的组件是子组件,使用了子组件名如<son>这里写准备插入子组件的内容</son>的是父组件)
这是区分插槽中的父子组件的标志,

对插槽的再次理解

即父组件把准备入子组件中的内容放在子组件占位符中,
(如<son>插入内容</son>,在实际开发中插入内容可以是好几层标签,十几到几十行或者更多行代码),
而子组件预留一个位,在需要放置插入内容的位置留下<slot></slot>,代表此处即将被放入父组件插入的内容

2.插槽的种类
  • 匿名插槽:没给插槽slot起名字,也叫默认插槽
  • 具名插槽:给slot起名字(定义具名插槽:使用到name特性)
  • 作用域插槽:本质是携带信息的匿名插槽

二.匿名插槽,具名插槽和作用域插槽的定义和使用:在网页和在项目中的使用示例

1.匿名插槽
1.1.匿名插槽定义和用法

略 详见上面的插槽介绍

1.2.在网页使用匿名插槽
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    h3{
      color:blueviolet
    }
  </style>
</head>
<body>
  <!--默认存在一个根组件,是所有组件的父组件 -->
  <div id="app">
    <niming>匿名</niming>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 
<script>
  //全局注册子组件niming
  Vue.component("niming",{
    template:`<div>我是<h3><slot></slot></h3>插槽</div>`
  });
  new Vue({
    el:"#app"
  })
</script>
</html>

在这里插入图片描述

1.3.vue项目中使用匿名插槽

(正确单词应该是component不是componment,下同)

  • 父组件:FatherComponment.vue
<template>
  <div>
    <son-componment>
    	<h3>匿名</h3>
    </son-componment>
  </div>
</template>

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

<style scoped>
</style>
  • 子组件SonComponment.vue
<template>
  <div>
    <!-- 我是<h3><slot></slot></h3>插槽 -->
    我是<slot></slot>插槽
  </div>
</template>

<script>
export default {

};
</script>
<style scoped>
h3{
  color:blueviolet
}
</style>
  • 在router/index.js中引入父组件
import Vue from 'vue'
import VueRouter from 'vue-router'

import Father from "../views/FatherComponment"
Vue.use(VueRouter)

const routes = [{
        path: '/',
        component: Father
    }
]

const router = new VueRouter({
    routes
});

export default router
2.具名插槽
2.1.具名插槽的定义和用法
  • 形式
    子组件把多个插槽放置在不同地方,父组件根据插槽名字填充对应内容
  • v-slot指令
    在向具名插槽提供内容的时候,我们可以在template元素上使用v-slot指令, 并以参数的形式提供其名称
    (一般是在vue项目中使用,如父组件中使用<template v-slot="juming">插入子组件的内容</template>)
  • name特性
    slot元素有一个特殊的特性:name ,这个特性可以用来定义额外的插槽
    (,而子组件使用<slot name="juming"></slot>来放置来自父组件的内容)
2.2.在网页中使用具名插槽
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    h3{
      color:blueviolet
    }
  </style>
</head>
<body>
   <!--默认存在一个根组件,是所有组件的父组件 -->
  <div id="app">
    <!-- 匿名插槽 -->
    <niming>匿名</niming>
    <!-- 具名插槽 -->
    <juming>
      <div>商品参数</div>
      <div><img src="https://ftp.bmp.ovh/imgs/2021/05/b86a125cadd68fb3.png" alt=""></div>
      <div slot="toubu">头部</div>
      <div slot="weibu">尾部</div>
    </juming>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 
<script>
  //全局注册子组件niming
  Vue.component("niming",{
    template:`<div>我是<h3><slot></slot></h3>插槽</div>`
  });
  //全局注册子组件juming
  Vue.component("juming",{
    template:`<div>
                  <header>
                    <slot name="toubu"></slot>  
                  </header>
                  <main>
                    <slot></slot>  
                  </main>
                  <footer>
                    <slot name="weibu"></slot>  
                  </footer>
              </div>`
  });
  new Vue({
    el:"#app"
  })
</script>
</html>

在这里插入图片描述
此例中,父组件中img图片本来放在最上面,渲染出来却变成了在中间
这是因为子组件把除了两个具名插槽的内容以外的部分,都渲染进了匿名插槽中
也就是说,父组件的标签顺序不代表最后渲染出来的最终样式

2.3.在vue项目中使用具名插槽
  • 父组件:FatherComponment.vue
<template>
  <div>
    <!-- 匿名插槽 -->
    <!-- <son-componment>匿名</son-componment> -->
    <!-- 具名插槽 -->
    <son-componment>
      <div>商品信息</div>
      <template v-slot:toubu>头部</template>
      <template v-slot:weibu>尾部</template>
      <div><img src="https://ftp.bmp.ovh/imgs/2021/05/b86a125cadd68fb3.png" alt=""></div>
    </son-componment>
  </div>
</template>

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

<style scoped>
</style>
  • 子组件SonComponment.vue
<template>
  <div>
    <header>
      <slot name="toubu"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="weibu"></slot>
    </footer>
  </div>
</template>

<script>
export default {

};
</script>

<style scoped>

</style>
  • 在router/index.js中引入父组件
2.4.具名插槽在网页中使用和在项目中使用的格式区别

在网页中
父组件是通过在子组件占位符中的带有slot的div标签<div slot="toubu">头部</div>来准备插入内容的

<juming>
  <div slot="toubu">头部</div>
  <div slot="weibu">尾部</div>
</juming>

子组件是通过在需要的位置预留槽位<slot name="toubu"></slot> 来实现放置插入内容的

 Vue.component("juming",{
   template:`<div>
                 <header>
                   <slot name="toubu"></slot>  
                 </header>
             </div>`
             ...
 });

在项目中
父组件是通过在子组件占位符中使用带有v-slot的template标签, <template v-slot:toubu>头部</template>来准备插入内容的:

<son-componment>
  <template v-slot:toubu>头部</template>
  <template v-slot:weibu>尾部</template>
</son-componment>

子组件是通过在需要的位置预留槽位<slot name="toubu"></slot> 来实现放置插入内容的(跟在网页中的格式一样)

<template>
    <header>
      <slot name="toubu"></slot>
    </header>
    ...
</template>
3.作用域插槽
3.1.作用域插槽的定义和用法
  • 定义
    本质是一个携带信息的匿名插槽
  • 形式
    作用域插槽可以携带数据:子组件提供数据,父组件提供样式
  • 插槽可以访问相同的实例属性,即相同的"作用域",
    访问子组件作用域时,把需要传递的内容绑到 slot 上,在父组件中用v-slot设置一个值来定义我们提供插槽的名字
  • 插槽 prop
    绑定在元素上的特性。
    在父组件中,用 v-slot 设置一个值来定义我们提供的插槽 prop 的名字,然后直接使用
3.2.在网页中使用作用域插槽(匿名)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
   <!--默认存在一个根组件,是所有组件的父组件 -->
  <div id="app">
    <!-- 作用域插槽 -->
    <zuoyongyu>
      <span slot-scope="library">查询书籍:{{library.info}}</span>
    </zuoyongyu>
  </div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 
<script>
  //全局注册子组件zuoyongyu
  Vue.component("zuoyongyu",{
    data(){
      return{
        book:"javascript从入门到精通"
      }
    },
    template:`<h1><slot :info="book"></slot>,剩余馆藏:2</h1>`
  });
  new Vue({
    el:"#app"
  });
  /*
  zuoyongyu:子组件
  library:slot-scope接收的对象
  info:library对象的属性
  slot-scope:父组件通过 “slot-scope” 来接收子组件传过来的插槽数据,再根据插槽数据来填充插槽的内容
  */
</script>
</html>

在这里插入图片描述

3.3.在vue项目中使用作用域插槽(匿名插槽)

Center.vue:v-slot写在Login上

    <Login v-slot:default="slotProp">
      <span>{{slotProp.usertext.firstname}}</span>
      <span>{{slotProp.usertext.lastname}}</span>
    </Login>

这里的default是指子组件中是一个匿名插槽,由此可见,可以把default换成具名插槽
Login.vue

<template>
  <div>
    <slot v-bind:usertext="myname"></slot>
  </div>
</template>
<script>
export default {
  data(){
    return{
      myname:{
        firstname:"张",
        lastname:"三"
      }
    }
  }
}
</script>
3.4.在vue项目中使用作用域插槽(具名插槽)

Center.vue:v-slot写在template上

<Login>
	 <template v-slot:header="slotProp">
	 	  <span>{{slotProp.usertext.firstname}}</span>
	 </template>
	 <template v-slot:footer="slotProp">
	  	 <span>{{slotProp.usertext.lastname}}</span>
	 </template>
</Login>

Login.vue:v-bind省略

<header> <slot name="header" :usertext="myname"></slot></header>
<footer> <slot name="footer" :usertext="myname"></slot></footer>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端OnTheRun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值