普通插槽、具名插槽、作用域插槽

插槽

插槽就是子组件提供给父组件的占位符,用slot来表示,父组件可以在这个占位符中填充各种的模板代码。

为什么要使用插槽?

你可能不太明白为什么要给子组件传入HTML而不是直接写在子页面中内,如果出现这种情况,你有五个子页面这五个子页面只有一小部分内容不一样。你会怎么做呢?最笨的办法就是复制代码,但在Vue中更加简便的方法就是插槽。

插槽的分类:

普通插槽、具名插槽、作用域插槽

普通插槽

子组件son.vue:

<template>
  <div>
   <slot></slot>
  </div>
</template>

父组件

<template>
  <div>
    <p>我是父组件</p>
    <Son>  
      验证插槽是否生效      //用son组件标签包裹内容,验证slot
    </Son>
  </div>
</template>
<script>
import Son from './son.vue'
export default {
    
    
  name:'parent',
  components:{
    
    
    Son
  }
</script>

具名插槽

具名插槽就是每个插槽带有自己的名字,在父组件中用到v-slot,也可以直接缩写为#

子组件:

<template>
  <div class="about">
    <h1>子组件</h1>
	<!--普通插槽-->
	<slot></slot>
    <!-- 给插槽加了个name属性,就是所谓的具名插槽了 -->
    <slot name="one"></slot>
    <slot name="two"></slot>
  </div>
</template>

父组件

<template>
  <div class="about">
    <h1>父组件</h1>
    <children>
      <template v-slot:one>
        <p>one插槽</p>
      </template>
      <template v-slot:two>
        two插槽
      </template>
    </children>
  </div>
</template>

作用域插槽

作用域插槽可以传递参数。

子组件

<template>
  <div class="about">
    <h1>This is an Children page</h1>
    <slot :obj1="obj1" name="one"></slot>
    <slot :obj2="obj2" name="two"></slot>
  </div>
</template>
<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      obj1: {
    
    
        name: 'one slot'
      },
      obj2: {
    
    
        name: 'two slot'
      }
    }
  }
}
</script>

父组件

<template>
  <div class="about">
    <h1>This is an Parent page</h1>
    <children>
        <template v-slot:one="slotProps">
          <h2>{
    
    {
    
    slotProps.obj1.name}}</h2>
        </template>
        <template v-slot:two="twoSlotProps">
          <h2>{
    
    {
    
    twoSlotProps.obj2.name}}</h2>
        </template>
    </children>
  </div>
</template>
<script>
import Children from './Children.vue'
export default {
    
    
  components: {
    
    
    Children
  },
  data () {
    
    
    return {
    
    
    }
  }
}
</script>

在这里插入图片描述

动态插槽

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

子组件:

<template>
  <div class="about">
    <h1>This is an Children page</h1>
    <slot :obj="obj1" name="one"></slot>
    <slot :obj="obj2" name="two"></slot>
  </div>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      obj1: {
    
    
        name: 'one slot'
      },
      obj2: {
    
    
        name: 'two slot'
      }
    }
  }
}
</script>

父组件:

<template>
  <div class="about">
    <h1>This is an Parent page</h1>
    <children>
        <template v-slot:[dynamicSlotName]="slotProps">
          <h2>{
    
    {
    
    slotProps.obj.name}}</h2>
        </template>
    </children>
  </div>
</template>

<script>
import Children from './Children.vue'
export default {
    
    
  components: {
    
    
    Children
  },
  data () {
    
    
    return {
    
    
      dynamicSlotName: 'one'
    }
  }
}
</script>

img

总结

slot又名插槽,是Vue的内容分发机制,组件内部的模板弓|擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。

slot又分三类,默认插槽,具名插槽和作用域插槽。

  • 默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认插槽,一个组件内只有一个匿名插槽。
  • 具名插槽:带有具体名字的插槽, 也就是带有name属性的slot, 一个组件可以出现多个具名插槽。
  • 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。

实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. $slot中,默认插槽为vm. $slot .default,具名插槽为vm. $slot.xxx , xx为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot 中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。

猜你喜欢

转载自blog.csdn.net/qq_46285118/article/details/129655841