博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Vue学习笔记-深入组件(插槽slot)

Posted on 2019-06-17 19:18  追风0315  阅读(1005)  评论(0编辑  收藏  举报

在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。

它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性。新语法的由来可查阅这份 RFC

 

插槽内容:文字,html片段,其他组件,如果没有<slot> 插槽,那么其中的任何内容都会被扔掉

<navigation-link>//组件内容

<a v-bind:href="url" class="nav-link" > <slot></slot> </a>

<navigation-link url="/profile">
  Your Profile
</navigation-link>

这样渲染成

 

//其他任何模板代码

<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>


<a url="/profile" class="nav-link" > 

<span class="fa fa-user"></span>
  Your Profile
 </a>

 

编译作用域:本页面的作用域,不能访问navigation-link内部作用域

父级模板里的所有内容都是在父级作用域中编译的;

子模板里的所有内容都是在子作用域中编译的。

<navigation-link url="/profile">
  Logged in as {{ user.name }} //user 指向本页面作用域
</navigation-link>

后备内容:组件默认数据,你不传给我东西,我就展示自己数据!

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

<button type="submit">
  <slot>Submit</slot>
</button>

 

具名插槽:<slot name="name"></slot>

<base-layout>组件

<div class="container">
  <header>
    <!-- 我们希望把页头放这里 -->
  </header>
  <main>
    <!-- 我们希望把主要内容放这里 -->
  </main>
  <footer>
    <!-- 我们希望把页脚放这里 -->
  </footer>
</div>

1:一个不带 name 的 <slot> 出口会带有隐含的名字“default”。
2:在向具名插槽提供内容,用template v-slot
3:注意 v-slot 只能添加在一个 <template> 上
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

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

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

 

作用域插槽:让插槽内容能够访问子组件中才有的数据 

有时让插槽内容能够访问子组件中才有的数据是很有用的

只有 <current-user> 组件内可以访问到 user 而我们提供的内容是在父级渲染的。

 

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

 

 

 

独占默认插槽的缩写语法:

这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 v-slot 被假定对应默认插槽

注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:

<current-user v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
</current-user>
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

 

出现多个插槽,请为所有插槽使用完这个的template语法
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>

 

解构插槽 Prop:作用域插槽组件数据传递出来,内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里

这个地方看得有点蒙圈!

function (slotProps) {
  // 插槽内容
}

动态插槽名:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>

 

具名插槽的缩写:v-slot:header  缩写为#header,必须有name 

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

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

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
该缩写只在其有参数的时候才可用。这意味着以下语法是无效的

<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
  {{ user.firstName }}
</current-user>

<current-user #default="{ user }">
  {{ user.firstName }}
</current-user>