vue插槽:在引入的组件标签中书写的内容是不会显示的,如果要显示这部分内容,需要用到<slot></slot>

 

1、插槽的概念:

比如说在Father组件中引入了Child组件,

Father:

<template>
  <div>
    <Child url="http://www.baidu.com">
      <p>百度</p>
    </Child>
  </div>
</template>

Child:

<template>
  <div>
    <a :href="url" target="_blank">
      <slot></slot>
    </a>
  </div>
</template>
<script>
  export default {
    props: ['url']
  }
</script>

如果不在Child中写slot标签,那么在Father组件中 <p>百度</p> 就不会有显示

 

2、具名插槽和匿名插槽:

Father:

<template>
  <div>
    <Child>
      <div slot="header">
        <h1>标题</h1>
      </div>
      <div>
        <p>内容</p>
      </div>
      <div slot="footer">
        <p>底部</p>
      </div>
    </Child>
  </div>
</template>

Child:

<template>
  <div>
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

此时,在父组件中的具名插槽和匿名插槽会对应地显示在子组件相应的位置,注意2.6.0+版本后,父组件中的写法:

<template>
  <div>
    <Child>
      <template v-slot:header>
        <h1>标题</h1>
      </template>
      <template>
        <p>内容</p>
      </template>
      <template v-slot:footer>
        <p>底部</p>
      </template>
    </Child>
  </div>
</template>

 

3、插槽作用域

前面父传子使用的是props,那么子传父怎么办呢?

①先在子组件中用v-bind绑定一个属性值

<template>
  <div>
    <a :href="url" target="_blank">
      <slot :val='"我是要传给父组件的值"'></slot>
    </a>
  </div>
</template>

②在父组件中通过 v-slot='slotProps' 获取到属性集合对象

<template>
  <div>
    <Child v-slot='slotProps'>
      <p>{{slotProps.val}}</p>
    </Child>
  </div>
</template>

也可以通过解构赋值的方式直接获取到当前属性

<template>
  <div>
    <Child url='xxx' v-slot='{val}'>
      <p>{{val}}</p>
    </Child>
  </div>
</template>

4、具名插槽作用域

Child:

<template>
  <div>
    <header>
      <slot name="header" :val='111'></slot>
    </header>
    <main>
      <slot :val='100'></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

Father:

<template>
  <div>
    <Child>
      <template v-slot:header={val}>
        <h1>标题</h1>
        <p>{{val}}</p>
      </template>
      <template v-slot='{val}'>
        <p>内容</p>
        <p>{{val}}</p>
      </template>
      <template v-slot:footer>
        <p>底部</p>
      </template>
    </Child>
  </div>
</template>