学习Vue之路——插槽

2018-12-27  本文已影响0人  小螃蟹_5f4c

在学习Vue的时候,面试的时候经常会被问到插槽,之前不会的时候让我自己封装一个tab插件的思路是什么,我傻傻的说传一个数据对象进去。。面试官就不理我了。。。
插槽主要分成三种:单个插槽,具名插槽和作用域插槽
单个插槽
单个插槽是最简单易懂的和最常用的;在模版中使用插槽可接受模版使用的时候传过来的内容,替代模版內的默认内容,向组件中传递不带 slot 特性的子元素时,比如test中的乖乖,这些子元素被存储在组件实例中的 $slots.default
有一个组件test;test模版里面的代码

<template>
    <h1>hello!</h1>
    <slot>使用的时候没有传入数据是我的内容显示,传入内容我就不显示</slot> //插槽的默认内容
</template>

有一个组件需要使用这个test组件,在使用的时候的用法:

<test>乖乖</test> //最后结果显示hello!乖乖

由于我实在太懒了 下面直接拿官方的例子

使用场景:
在同一样的结构下,某一个部分下需要使用不同的模版,假如我有一个页面,拥有同一样的头和尾 这个时候我就只需要给中间的部分传一个不同的slot,可以拥有不同的数据结构。我自己理解的与子组件的不同之处是这个可以传入不同的html结构,而子组件只能传入数据,结构是一样的。 还有ui组件的tab组件的内容就是使用了slot

具名插槽
有些时候我们需要多个插槽。简单来说,就是需要给插槽命名,分别窜地给名字相同的地方。对于这样的情况,<slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽。定义的组件里面的代码:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot> //这个是未命名插槽,在使用的时候未指定名字的将会匹配到这里
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

在向具名插槽提供内容的时候,我们可以在一个父组件的 <template> 元素上使用 slot 特性,或者直接用在普通元素上也是可以的

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

   <p slot="footer">Here's some contact info</p>
</base-layout>

应用场景:这个比较灵活,比如一个页面有多处需要分发不同的内容的时候使用。

作用域插槽
提供的组件带有一个可从子组件获取数据的可复用的插槽。简单说来跟前面两种不同的情况就是 前面两种渲染的数据是从使用的组件决定,作用域插槽就是数据由封装的组件决定
在通过slot元素,使用v-bind的形式绑定属性传递给父元素,父元素通过slot-scope属性来接收属性
定义组件:

<ul>
  <li v-for="todo in todos" :key="todo.id">
    <!-- 我们为每个 todo 准备了一个插槽,-->
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot :todo="todo"> //这里的todo就是传递给父元素接受的数据
      <!-- 回退的内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

使用的时候的组件:

<todo-list v-bind:todos="todos"> 这里todo-list里面使用的数据是通过props传递进去的,也可以在子元素里面定义数据
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps">  //slotProps是接收todo-list传过来的数据的
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

使用场景:同样的内容和数据在不同的地方使用不同的样式可使用作用域插槽。在父组件里面自定义样式。(自己的理解,可能不对)。

上一篇 下一篇

猜你喜欢

热点阅读