一、插槽内容


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

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

  1. <navigation-link url="/profile">                                      HTML
  2. Your Profile
  3. </navigation-link>

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

  1. <a                                                        HTML
  2. v-bind:href="url"
  3. class="nav-link"
  4. >
  5. <slot></slot>
  6. </a>

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

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

甚至其他的组件:

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

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

二、具名插槽


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

  1. <div class="container">                                            HTML
  2. <header>
  3. <!-- 我们希望把页头放这里 -->
  4. </header>
  5. <main>
  6. <!-- 我们希望把主要内容放这里 -->
  7. </main>
  8. <footer>
  9. <!-- 我们希望把页脚放这里 -->
  10. </footer>
  11. </div>

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

  1. <div class="container">                                            HTML
  2. <header>
  3. <slot name="header"></slot>
  4. </header>
  5. <main>
  6. <slot></slot>
  7. </main>
  8. <footer>
  9. <slot name="footer"></slot>
  10. </footer>
  11. </div>

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

  1. <base-layout>                                                   HTML
  2. <template slot="header">
  3. <h1>Here might be a page title</h1>
  4. </template>
  5.  
  6. <p>A paragraph for the main content.</p>
  7. <p>And another one.</p>
  8.  
  9. <template slot="footer">
  10. <p>Here's some contact info</p>
  11. </template>
  12. </base-layout>

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

  1. <base-layout>                                                  HTML
  2. <h1 slot="header">Here might be a page title</h1>
  3.  
  4. <p>A paragraph for the main content.</p>
  5. <p>And another one.</p>
  6.  
  7. <p slot="footer">Here's some contact info</p>
  8. </base-layout>

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

  1. <div class="container">                                            HTML
  2. <header>
  3. <h1>Here might be a page title</h1>
  4. </header>
  5. <main>
  6. <p>A paragraph for the main content.</p>
  7. <p>And another one.</p>
  8. </main>
  9. <footer>
  10. <p>Here's some contact info</p>
  11. </footer>
  12. </div>

三、插槽的默认内容


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

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

  1. <button type="submit">                                              HTML
  2. <slot>Submit</slot>
  3. </button>

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

四、编译作用域


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

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

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

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

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

五、作用域插槽


2.1.0+新增

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

  1. <ul>                                                        HTML
  2. <li
  3. v-for="todo in todos"
  4. v-bind:key="todo.id"
  5. >
  6. {{ todo.text }}
  7. </li>
  8. </ul>

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

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

  1. <ul>                                                        HTML
  2. <li
  3. v-for="todo in todos"
  4. v-bind:key="todo.id"
  5. >
  6. <!-- 我们为每个 todo 准备了一个插槽,-->
  7. <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
  8. <slot v-bind:todo="todo">
  9. <!-- 回退的内容 -->
  10. {{ todo.text }}
  11. </slot>
  12. </li>
  13. </ul>

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

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

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

5.1解构 slot-scope

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

  1. <todo-list v-bind:todos="todos">
  2. <template slot-scope="{ todo }">
  3. <span v-if="todo.isComplete"></span>
  4. {{ todo.text }}
  5. </template>
  6. </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. 使用systemd严格保证启动顺序

    需求: 服务B要在服务A之后启动,且由于存在强内在依赖关系,B必须在A完成初始化之后才能被启动. 解决方法: 首先使用systemd,service脚本需要配置服务B要after服务A. 其次,A服务 ...

  2. 【转】Ubuntu12.04 LTS下环境变量设置

    原文网址:http://blog.chinaunix.net/uid-26963688-id-3221439.html 1.设置当前用户环境变量(对root用户无效) 打开终端输入:light@cha ...

  3. spark之 spark 2.2.0 Standalone安装、wordCount演示

    说明:前提安装好hadoop集群,可参考 http://blog.csdn.net/zhang123456456/article/details/77621487 一. scala 安装 1.下载 s ...

  4. 声明变量(Declared Variable)和非声明变量(Undeclared Variable)的区别

    声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的. 声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作的时候才会被创建. 声明变量是它所在上下文环境的不可配置属性(non- ...

  5. python类的继承的两种方式

    class Animal(object): """docstring for Animal""" def __init__(self, na ...

  6. Flask视图函数与普通函数的区别,响应对象Response

    视图函数与普通函数看似没什么区别,其实他们的返回值上有着很大的区别. from flask import Flask app = Flask(__name__) @app.route('/hello' ...

  7. MySQL excel导入

    说明: 1 因在测试发现如果用SQLyog导入数据需要下载excel驱动,因而选择Navicat 2 之前选择excel文件为xlsx 发现Navicat识别不了,因而转存为xls文件,测试OK 1  ...

  8. [UE4]动画序列面板

  9. VMware仅主机模式访问外网

    原文转载至:https://blog.csdn.net/eussi/article/details/79054622 保证VMware Network Adapter VMnet1是启用状态  将可以 ...

  10. IntelliJ IDEA小问题解决方法------(持续更新)

    1:IDEA运行时报错提示“找不到或无法加载主类”:在确保IDEA开发环境无误后->file->invalidate Cache/restart,之后再重新build.问题解决. 2.如何 ...