Vue中插槽的使用详解

1.介绍

插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签。通俗的说是:slot 是在父组建控制了子组件显示或隐藏相关内容。

插槽又分为三种,1.普通插槽 2.具命插槽 3.作用域插槽

1.普通插槽

子组件

<template id="childrenApp">
    <div>
        <!-- 插槽 slot  此时slot标签就代表 组件标签中的内容-->
        <slot></slot>
        <button>文本1</button>
        <slot></slot>
        <button>文本2</button>
        <slot></slot>
    </div> 

</template>

父组件

<template>
   <div id="app">
    <children-app> 
        <p>组件标签中的内容 {{msg}}</p>
        <h3>标题</h3>
    </children-app>
  </div>
</template>

注:如果 <children-app> 的 template 中没有包含一个 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。

2.具名插槽

在一个组件中有多个插槽,调用的时候为了给不同的组件传递,
参数就需要为插槽进行命名。为不同需求的组件传递不同的参数。

子组件

<template id="childrenApp">
    <div>
        <!-- 插槽 slot  此时slot标签就代表 组件标签中的内容-->
        <slot name="header"></slot>
        <slot name="footer"></slot>
    </div> 

</template>

父组件

<template>
   <div id="app">
    <children-app> 
        <template v-slot:header><h3>This is header</h3></template>
        <template v-slot:main><h3>This is main</h3></template>
        <template #footer> <h3>This is footer</h3></template>
        <!-- #footer和v-slot:footer的使用效果是相同的 -->
    </children-app>
  </div>
</template>

3.作用域插槽 - 父组件读取子组件数据

作用域插槽的样式由父组件决定,内容却由子组件控制。前两种插槽不能绑定数据,作用域插槽是一个带绑定数据的插槽。简单的来说就是子组件提供给父组件参数,该参数仅限于插槽中使用,父组件可以根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽的内容。

有时让插槽内容能够访问子组件中才有的数据是很有用的。例如,设想一个带有如下模板的
子组件封装的内容

<span>
    <slot>{{ user.lastName }}</slot>
</span>

而我们在父组件引用,想换掉现有子组件预留的显示内容

<children-app>
    {{ user.firstName }}
</children-app>

然而上述代码不会正常工作,因为只有 <children-app> 组件可以访问到 user 而我们提供的内容是在父级渲染的。

解决方式:
为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 元素的一个 attribute 绑定上去:
子组件

<template id="childrenApp">
    <span>
      <slot v-bind:user="user">
          {{ user.lastName }}
      </slot>
    </span> 
</template>
//  或者 官网举例
<template id="childrenApp">
    <span>
      <slot :text="greetingMessage" :count="1"></slot>
    </span> 
</template>

绑定在 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:
父组件

<template>
   <div id="app">
    <children-app> 
        <template v-slot:default="slotProps">
          {{ slotProps.user.firstName }}
        </template>
    </children-app>
  </div>
</template>
// 官网举例  -  父组件写法
<template>
   <div id="app">
    <MyComponent v-slot="slotProps">
      {{ slotProps.text }} {{ slotProps.count }}
    </MyComponent>
  </div>
</template>
posted @ 2022-06-24 13:59  seekHelp  阅读(311)  评论(0编辑  收藏  举报