Vue 之 插槽的使用,一次性给你说清楚

目录

一、 认识插槽

二、使用插槽

1.普通插槽

插槽组件

使用插槽

查看效果

 2.具名插槽

插槽组件

使用插槽

 查看效果

 3.作用域插槽 

插槽组件

使用插槽

查看效果 


前言 : 在开发中,我们会经常封装一个个复用的组件,大部分都是传递不同的数据,让组件来进行展示,template结构都是固定的

那么,有没有一种可能,可以让使用者来决定某一块区域到底存放什么内容和元素呢

答案是有的,那就是使用插槽,根据传入的不同,显示特定的内容 

一、 认识插槽

这个时候我们就可以使用插槽

  • 插槽的使用过程其实是抽取共性、预留不同
  • 将共同的元素、内容依然在组件内进行封装
  • 将不同的元素使用slot作为占位,让外部决定到底显示什么元素

二、使用插槽

vue中将<slot>元素作为承载分发内容的出口,使用<slot>就可以为封装组件开启一个插槽

1.普通插槽

插槽组件

<template>
  <div>
    <h2>组件开始</h2>
    <!-- 安放一个插槽,可以使用默认值,若没有东西插进来就显示这个-->
    <slot>333</slot>
    <h2>组件结束</h2>
  </div>
</template>

<script>
export default {};
</script>
<style scoped></style>

使用插槽

<template>
  <div class="HelloWorld-layout">
    <div>HelloWorld</div>
    <!-- 中间不写内容,显示默认内容 -->
    <my-slot></my-slot>
    <!-- 覆盖默认值 中间也可以插入文本、自定义组件,各种东西~ -->
    <my-slot>
      <h1>哈哈哈</h1>
    </my-slot>
  </div>
</template>
<script>
import MySlot from './mySlot.vue';
export default {
  name: 'HelloWorld',
  components: { MySlot }
};
</script>
<style scoped></style>

查看效果


 2.具名插槽

给插槽绑定一个name属性,也就是取个名字,使用的时候可以找到对应的插槽把内容放入

插槽组件

<template>
  <div class="nav-bar">
    <div class="default">
      <!-- 其实这样默认名字是default  <slot name="default"></slot> -->
      <slot></slot>
    </div>
    <div class="left">
      <!-- 定义左边的插槽 -->
      <slot name="left"></slot>
    </div>
    <div class="center">
      <!-- 定义中间的插槽 -->
      <slot name="center"></slot>
    </div>
    <div class="right">
      <!-- 定义右边的插槽 , 使用传递过来的name值来动态绑定 -->
      <slot :name="dynamicSlotName"></slot>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    // 接受父组件的传值
    dynamicSlotName: {
      type: String,
      default: ''
    }
  }
};
</script>
<style scoped>
.nav-bar {
  display: flex;
  text-align: center;
}
.default,
.left,
.center,
.right {
  flex: 1;
}
</style>

使用插

<template>
  <div class="HelloWorld-layout">
    <!-- 传递一个动态的name过去 -->
    <my-slot :dynamic-slot-name="dynamicSlotName">
      <!-- 找到默认的插槽  和这个是一样的  <template v-slot:default> 我是left </template>-->
      <span>我找默认的插槽</span>
      <!-- 找到名称为left的插槽 -->
      <template v-slot:left> 我是left </template>
      <!-- 找到名称为center的插槽  这是语法糖(简便写法) -->
      <template #center> 我是center </template>
      <!-- 找到名称为right的插槽 , 使用变量来绑定 -->
      <template #[dynamicSlotName]> 我是right </template>
    </my-slot>
  </div>
</template>
<script>
import MySlot from './mySlot.vue';
export default {
  name: 'HelloWorld',
  components: { MySlot },
  data() {
    return {
      dynamicSlotName: 'right'
    };
  }
};
</script>
<style scoped></style>

 查看效果


 3.作用域插槽 

在vue中有渲染作用域的概念

  • 父级模版里的所有内容都是在父级作用域中编译
  • 子模版里的所有内容都是在子作用域中编译

tip : 也就是说,在父组件中是访问不到子组件的内容的,虽然在父组件中使用了插槽,内容是插进了子组件中,但是还是不能访问子组件中定义的变量

插槽组件

<template>
  <div class="nav-bar">
    <!-- 注意,这里是子组件,给子组件的slot上绑定上一个数据 -->
    <slot name="bar" :title-arr="titleArr"></slot>

    <!-- 默认插槽 -->
    <slot :default-arr="defaultArr"></slot>
  </div>
</template>
<script>
export default { 
  data() {
    return {
      titleArr: ['a', 'b', 'c', 'd'],
      defaultArr: ['d', 'e', 'f', 'a', 'u', 'l', 't']
    };
  }
};
</script>
<style scoped>
.nav-bar {
  display: flex;
  flex-direction: column;
  text-align: center;
}
</style>

使用插槽

<template>
  <div class="HelloWorld-layout">
    <my-slot>
      <!-- 使用具名插槽的同时,使用子组件中传递过来的数据,数据都放在slotProps这个对象中 -->
      <template #bar="slotProps">
        <!-- 取出slotProps中我们绑定的titleArr变量,进行使用 -->
        <ul class="nav">
          <li class="item" v-for="item in slotProps.titleArr" :key="item">{
   
   { item }}</li>
        </ul>
        <!-- 从插槽里面拿出数据,可以在外部自己控制用什么来包裹 -->
        <div class="button-box">
          <button v-for="item in slotProps.titleArr" :key="item">{
   
   { item }}</button>
        </div>
      </template>
    </my-slot>

    <!-- 当只使用默认插槽(没有取名字时),只使用一个,可以简写成这样(不写template)   官方名称 : 独占默认插槽的缩写-->
    <my-slot v-slot="slotProps">
      <div class="default-box">
        <span v-for="item in slotProps.defaultArr" :key="item">{
   
   { item }}</span>
      </div>
    </my-slot>
  </div>
</template>
<script>
import MySlot from './mySlot.vue';
export default {
  name: 'HelloWorld',
  components: { MySlot }
};
</script>
<style scoped>
.nav {
  width: 100%;
  display: flex;
  padding: 0;
  margin-left: 8px;
  list-style: none;
}
.item,
.button-box button,
.default-box span {
  flex: 1;
  height: 60px;
  line-height: 60px;
  background-color: skyblue;
  margin-right: 8px;
  margin-top: 30px;
}
.button-box,
.default-box {
  width: 100%;
  display: flex;
  margin-left: 8px;
}
.button-box button {
  background-color: red;
  border: none;
  cursor: pointer;
}
</style>

查看效果 


tip : 这边文章总的来说不难,不过细节还是挺多的

猜你喜欢

转载自blog.csdn.net/a15297701931/article/details/118081833