前端基础Vue项目中的插槽使用

概念

简单理解就是组件内部留一个或多个的插槽位置,可供组件传对应的模板代码进去。插槽的出现,让组件变的更加灵活。

1. 匿名插槽

父组件
<son>
              <p>我是父组件通过匿名插槽传输的内容</p>
            </son>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 子组件

<template>
  <div>
    我是子组件
    <slot></slot>
  </div>
</template>
<script>
export default {
}
</script>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

样式

当然也可以直接在slot标签上写内容 ,比如

  <son>
            </son>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
<template>
  <div>
    我是子组件
    <slot>我是后补内容</slot>
  </div>
</template>
<script>
export default {
}
</script>
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

大白话就是父组件并没有传输内容,有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。

2. 具名插槽

顾名思义就是带名字的插槽,假如需要在组件内部预留多个插槽位置,就需要为插槽定义名字,指定插入的位置。

Vue 2.6.0+ 版本,使用v-slot替代slot 和 slot-scope。

注意点:
1.具名插槽的内容必须使用模板< template ></ template >包裹;
2.不指定名字的模板插入匿名插槽中,推荐使用具名插槽,方便代码追踪且直观清楚;
3.匿名插槽具有隐藏的名字"default;"
 

2.1 具名插槽的缩写


跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。
例如 v-slot:header 可以被重写为 #header;
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:


父组件

 <son :title="name">
              <template #header><p>我是头部</p></template>
              <template #body><p>我是身体</p>
              </template>
              <template v-slot:[name]><p>我是脚部</p>
              </template>
            </son>
子组件
<template>
  <div>
    我是子组件{
   
   {title}}
    <slot name="footer"></slot>
    <slot name='body'></slot>
    <slot name="header"></slot>
  </div>
</template>
<script>
export default {
  props: {
    title: String
  }
}
</script>

2.2 动态插槽名

动态指令参数也可以用在 v-slot 上,来定义动态的插槽名

<template v-slot:[name]><p>我是脚部</p>
              </template>

3. 作用域插槽

3.1 父传子

父组件
<son :title="name">
              <template #header><p>我是头部</p></template>
              <template #body><p>我是身体</p>
              </template>
              <template v-slot:[name]><p>我是脚部</p>
              </template>
            </son>
          </el-row>
子组件
<template>
  <div>
    我是子组件{
   
   {title}}
    <slot name="footer"></slot>
    <slot name='body'></slot>
    <slot name="header"></slot>
  </div>
</template>
<script>
export default {
  props: {
    title: String
  }
}
</script>

父组件传递的插槽内容是由子组件编译的,插槽作用域由子组件决定。
所以如果需要动态修改插槽的内容,就需要子组件传参给父组件。

3.2 子传父

父组件传参给子组件,props接收后,插槽slot再通过绑定属性传递参数返回给父组件,不管是模板代码还是数据,控制权完全掌握在父组件手里。

第一种方式

父组件
 <son :title="name">
              <template #header="header">{
   
   {header.header}}</template>
              <template #body="body">{
   
   {body.body}}
              </template>
              <template #footer="footer">{
   
   {footer.footer}}
              </template>
            </son>
子组件
<template>
  <div>
    我是子组件
    <slot name="footer" :footer="title.footer"></slot>
    <slot name='body' :body="title.body"></slot>
    <slot name="header" :header="title.header"></slot>
  </div>
</template>
<script>
export default {
  props: {
    title: Object
  }
}
</script>
样式

 第二种方式

子组件通过属性 <slot :自定义属性名 = '值'></slot>,将自己内部的原始类型给到父组件;
父组件 <template slote-scope='自定义接收'></template>;
子组件 slot 除了要占个位置还要传递参数,父组件 slote-scope 负责接收参数;
父组件
 <son :list="provinces">
              <template slot-scope="slotProps">
                <h4 v-for="city in slotProps.cities" :key="city.id" >
                  城市: {
   
   {city.name}}
                </h4>
              </template>
            </son>
子组件
<template>
  <div class="footerComponent">
    <div v-for="item in list" :key="item.id">
      <h2>省份:{
   
   {item.name}}</h2>
      <slot :cities="item.cities"></slot>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    title: Object,
    list: {
      type: Array,
      default: function() {
        return []
      }
    }
  }
}
</script>

父给子传 provinces,在son便签进行传,子组件接收用props,子给父传item.cities,父template用slot-scope接收。

猜你喜欢

转载自blog.csdn.net/2201_75705263/article/details/135077182