一、插槽内容


Vue实现了一套内容分发的API,这套API基于当前的Web Components规范草案,将 <slot>  元素作为承载分发的内容的出口。

它允许你像这样合成组件:

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

然后你在 <navigation-link> 的模板中可能会写为:

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

当组件渲染的时候,这个 <slot> 元素将会被替换为"Your Profile"。插槽内可以包含任何模板代码,包括HTML:

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

甚至其他的组件:

<navigation-link url="/profile">                                      HTML
  <!-- 添加一个图标的组件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

如果 <navigation-link> 没有包含一个 <slot> 元素,则任何传入它的内容都会被抛弃。

二、具名插槽


有些时候我们需要多个插槽。例如,一个假设的 <base-layout> 组件多模板如下:

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

对于这样的情况,<slot> 元素有一个特殊的属性: name。这个特性可以用来定义额外的插槽:

<div class="container">                                            HTML
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

在项具名插槽提供内容的时候,我们可以在一个父组件的 <template> 元素上使用 slot 特性:

<base-layout>                                                   HTML
  <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>

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

另一种 slot 特性的用法是直接用在一个普通的元素上:

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

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

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

我们还是可以保留一个未命名插槽,这个插槽是默认插槽,也就是说它会作为所有未匹配到插槽的内容的统一出口。上述两个示例渲染出来的HTML都将会是:

<div class="container">                                            HTML
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

三、插槽的默认内容


有的时候为插槽提供默认的内容是很有用的。例如,一个 <submit-button> 组件可能希望这个按钮的默认内容是"Submit",但是同事允许用户覆写为"Save"、"Upload"或别的内容。

你可以在 <slot> 标签内部制定默认的内容来做到这一点。

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

如果父组件为这个插槽提供了内容,则默认的内容会被替换掉。

四、编译作用域


当你想在插槽内使用数据时,例如:

<navigation-link url="/profile">                                        HTML
  Logged in as {{ user.name }}
</navigation-link>

该插槽可以访问跟这个模板的其他地方相同的实例属性(也就是说"作用域"是相同的)。

但这个插槽不能访问 <navigation-link> 的作用域。例如尝试访问 url 是不会工作的。牢记一条准则:

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

五、作用域插槽


2.1.0+新增

有的时候你希望提供的组件带有一个可从子组件获取数据的可复用的插槽。例如一个简单的 <todo-list> 组件的模板可能包含了如下代码:

<ul>                                                        HTML
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>

但是在我们应用的某些部分,我们希望每个独立的代办项渲染出和 todo.text 不太一样的东西。这也是作用域插槽的用武之地。

为了让这个特性成为可能,你需要做的全部事情就是将代办项内容包裹在一个 <slot> 元素上,然后将所有和其上下文香瓜你的数据传递给这个插槽:在这个例子中,这个数据时 todo 对象:

<ul>                                                        HTML
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 我们为每个 todo 准备了一个插槽,-->
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

现在当我们使用 <todo-list> 组件的时候,我们可以选择为待办项定义一个不一样的 <template> 作为替代方案,并且可以通过 slot-scope 特性从子组件获取数据:

<todo-list v-bind:todos="todos">                                      HTML
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps">
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

注意:在2.5.0,slot-scope不再限制在 <template> 元素上使用,而可以用在插槽内的任何元素或组件上。

5.1解构 slot-scope

如果一个 JavaScript 表达式在一个函数定义的参数位置有效,那么这个表达式实际上就可以被 slot-scope 接受。也就是说你可以在支持的环境下(单文件组件或现代浏览器),在这些表达式中使用ES2015解构语法。例如:

<todo-list v-bind:todos="todos">
  <template slot-scope="{ todo }">
    <span v-if="todo.isComplete">✓</span>
    {{ todo.text }}
  </template>
</todo-list>

这会使作用域插槽变得更干净一些。

vue深入了解组件——插槽的更多相关文章

  1. 04 . Vue组件注册,数据交互,调试工具及组件插槽介绍及使用

    vue组件 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  2. 04 . Vue组件注册,组件间数据交互,调试工具及组件插槽介绍及使用

    vue组件 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的 ...

  3. vue(3)—— vue的全局组件、局部组件

    组件 vue有局部组件和全局组件,这个组件后期用的会比较多,也是非常重要的 局部组件 template与components属性结合使用挂载 其中 Vmain.Vheader.Vleft.Vconte ...

  4. vue学习之组件

    组件从注册方式分为全局组件和局部组件. 从功能类型又可以分为偏视图表现的(presentational)和偏逻辑的(动态生成dom),推荐在前者中使用模板,在后者中使用 JSX 或渲染函数动态生成组件 ...

  5. Vue.js之组件系统

    vue.js既然是框架,那就不能只是简单的完成数据模板引擎的任务,它还提供了页面布局的功能.本文详细介绍使用vue.js进行页面布局的强大工具,vue.js组件系统. Vue.js组件系统 每一个新技 ...

  6. vue学习之四组件系统

    vue.js既然是框架,那就不能只是简单的完成数据模板引擎的任务,它还提供了页面布局的功能.本文详细介绍使用vue.js进行页面布局的强大工具,vue.js组件系统. 一.Vue.js组件系统 每一个 ...

  7. Vue 入门之组件化开发

    Vue 入门之组件化开发 组件其实就是一个拥有样式.动画.js 逻辑.HTML 结构的综合块.前端组件化确实让大的前端团队更高效的开发前端项目.而作为前端比较流行的框架之一,Vue 的组件和也做的非常 ...

  8. Vue 中的组件

    VUE中的组件 一个自定义的标签,vue就会把他看成一个组件,vue可以给这些标签赋予一定意义:一个页面就是一个组件 好处: 1.提高开发效率 2.方便重复使用 3.便于协同开发 4.更容易被管理和维 ...

  9. Vue框架之组件系统

    1,Vue组件系统之全局组件 1.1Vue全局组件的在实例化调用Vue的模板中导入组件的名称 <!DOCTYPE html> <html lang="zh-cn" ...

随机推荐

  1. Linux 命令英文全称

    Linux 命令英文全称 linux 命令 英文全称 sudo superuser do su swith user df Disk free,空余硬盘 du Disk usage,硬盘使用率 noh ...

  2. Generator 知识点

    Generator 函数的执行过程,其实是将同一个回调函数,反复传入 next 方法的 value 属性. Iterator 接口的 next 方法必须是同步的,只要调用就必须立刻返回值.也就是说,一 ...

  3. windows python3 安装gittle

    1 从github clone gittle项目, git clone https://github.com/FriendCode/gittle.git 2 进行到下载的项目,执行安装 python ...

  4. POJ3177(3352)(边双连通分量)

    题目: 原本没有记录桥是谁,而是染色时即时判断的.后来发现不行,因为a去b可能满足low[b]>dfn[a],但b去a就不满足了. 这是因为low和dfn的关系是相对的,仅限于tarjan时的那 ...

  5. codevs2189数字三角形(%100)

    题目:http://codevs.cn/problem/2189/ %100的话就加一维状态.把最优性改为可行性(存在性). #include<iostream> #include< ...

  6. Navicat导出opencart2.3数据字典

    步骤请参考:http://blog.csdn.net/maquealone/article/details/60764420 运行SQL:   备注:opcml是数据库名称. select TABLE ...

  7. CC2530中串口波特率改为9600时单个数据包来不及接收的解决方案

    在调试CC2530过程中发现波特率改为9600时,单个包仅有3个Byte时,接收DMA就会启动 因而数据包被强迫拆分成多个,显然只要将接收DMA启动延时做到足够大即可. 具体修改内容如下图所示: 经过 ...

  8. 实验三:C分支结构程序设计

    3.1 #include<stdio.h> int main(){ char a; scanf("%c",&a); if(a>=65&&a ...

  9. HSSF NPOI 颜色

    using System; using System.IO; using System.Windows.Forms; using NPOI.HSSF.UserModel; using NPOI.SS. ...

  10. Appium录制脚本520-2

    1.录制自动化脚本 场景:启动雪球,点击我的,登陆雪球,选择手机及其他登陆,输入手机号 2.使用Java进行测试Appium测试 2.1创建Java工程 file-创建maven工程-填写GroupI ...