Vue学习笔记入门篇——组件的内容分发(slot)

本文为转载,原文:Vue学习笔记入门篇——组件的内容分发(slot)

介绍

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” 如果你熟悉 Angular)。Vue.js 实现了一个内容分发 API,使用特殊的 ‘slot’ 元素作为原始内容的插槽。

编译作用域

在深入内容分发 API 之前,我们先明确内容在哪个作用域里编译。假定模板为:

<child-component>
    {{ message }}
</child-component>

message 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:

父组件模板的内容在父组件作用域内编译;
子组件模板的内容在子组件作用域内编译。

一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:

<!-- 无效 -->
<child-component v-show="someChildProperty"></child-component>

假定 someChildProperty 是子组件的属性,上例不会如预期那样工作。父组件模板不应该知道子组件的状态。
如果要绑定作用域内的指令到一个组件的根节点,你应当在组件自己的模板上做:

Vue.component(‘child-component‘, {
  // 有效,因为是在正确的作用域内
  template: ‘<div v-show="someChildProperty">Child</div>‘,
  data: function () {
    return {
      someChildProperty: true
    }
  }
})

类似地,分发内容是在父作用域内编译。

单个slot

除非子组件模板包含至少一个 ‘slot’ 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身。
最初在 ‘slot’ 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。
示例代码:

<div id="app">
    <h1>我是父组件的标题</h1>
    <my-component>
        <p>初始内容1</p>
        <p>初始内容2</p>
    </my-component>
</div>
Vue.component(‘my-component‘,{
    template:`
    <div>
        <h2>我是子组件的标题</h2>
        <slot>
            只有在没有要分发的内容是才出现。
        </slot>
    <div>
`,
})
new Vue({
    el:‘#app‘
})

运行结果如下:

将html部分代码修改为以下代码:

<div id="app">
    <h1>我是父组件的标题</h1>
    <my-component>
    </my-component>
</div>

则运行结果如下:

具名slot

‘slot’ 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的备用插槽。如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。
如以下例子:

<div id="app">
    <my-component>
        <h1 slot="header">这是标题</h1>
        <p>第一个段落</p>
        <p>第二个段落</p>
        <p>第三个段落</p>
        <p slot="footer">联系信息</p>
    </my-component>
</div>
Vue.component(‘my-component‘,{
    template:`
    <div class="container">
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <slot></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
    <div>
`,
})
new Vue({
    el:‘#app‘
})

运行结果如下:

在组合组件时,内容分发 API 是非常有用的机制。

作用域插槽

2.1.0新增

作用域插槽是一种特殊类型的插槽,用作使用一个 (能够传递数据到) 可重用模板替换已渲染元素。
在子组件中,只需将数据传递到插槽,就像你将 props 传递给组件一样。
示例代码:

<div id="app">
    <my-component>
        <template scope="props">
            <p>hello from parent</p>
            <p>{{props.text}}</p>
        </template>
    </my-component>
</div>
Vue.component(‘my-component‘,{
    template:`
    <div class="child">
        <slot text="hello from child"></slot>
    <div>
`,
    props:[‘text‘]
})
new Vue({
    el:‘#app‘
})

运行结果:

在父级中,具有特殊属性 scope 的 <’template’> 元素必须存在,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 props 对象。

作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项:

<div id="app">
    <my-component :items="items">
        <template slot="item" scope="props">
            <li>{{props.text}}</li>
        </template>
    </my-component>
</div>
Vue.component(‘my-component‘,{
    template:`
    <ul>
        <slot name="item" v-for="item in items" :text="item.text"></slot>
    </ul>
`,
    props:[‘text‘,‘items‘]
})
new Vue({
    el:‘#app‘,
    data:{
        items:[
            {text:‘item1‘},
            {text:‘item2‘},
            {text:‘item3‘},
        ]
    }
})

作用域插槽也可以是具名的
运行结果:

本文为原创,转载请注明出处。
上一节:Vue学习笔记入门篇——组件的通讯
返回目录
下一节:Vue学习笔记入门篇——组件杂项

时间: 2024-10-01 00:22:57

Vue学习笔记入门篇——组件的内容分发(slot)的相关文章

Vue学习笔记入门篇——组件的通讯

本文为转载,原文:Vue学习笔记入门篇--组件的通讯 组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B.它们之间必然需要相互通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件.然而,在一个良好定义的接口中尽可能将父子组件解耦是很重要的.这保证了每个组件可以在相对隔离的环境中书写和理解,也大幅提高了组件的可维护性和可重用性.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 props 向下传递

Vue学习笔记入门篇——组件的使用

本文为转载,原文:Vue学习笔记入门篇--组件的使用 组件定义 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 组件使用 注册 注册一个全局组件,你可以使用 Vue.component(tagName, options).组件在注册之后,便可以在父实例的模块中以自定义元素 的形式使用.

Vue学习笔记进阶篇——多元素及多组件过渡

本文为转载,原文:Vue学习笔记进阶篇--多元素及多组件过渡 多元素的过渡 对于原生标签可以使用 v-if/v-else.但是有一点需要注意: 当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容.即使在技术上没有必要,给在 <transition> 组件中的多个元素设置 key 是一个更好的实践. 示例: <transition> <button v-if="isEditing

Vue学习笔记进阶篇——Render函数

本文为转载,原文:Vue学习笔记进阶篇--Render函数 基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template 更接近编译器. <h1> <a name="hello-world" href="#hello-world"> Hello world! </a> </h1>

Vue学习笔记进阶篇——列表过渡及其他

本文为转载,原文:Vue学习笔记进阶篇--列表过渡及其他本文将介绍Vue中的列表过渡,动态过渡, 以及可复用过渡是实现. 列表过渡 目前为止,关于过渡我们已经讲到: 单个节点 同一时间渲染多个节点中的一个 那么怎么同时渲染整个列表,比如使用 v-for ?在这种场景中,使用 <transition-group>组件.在我们深入例子之前,先了解关于这个组件的几个特点: 不同于 <transition>, 它会以一个真实元素呈现:默认为一个<span>.你也可以通过 tag

Vue学习笔记进阶篇——过渡状态

本文为转载,原文:Vue学习笔记进阶篇--过渡状态Vue 的过渡系统提供了非常多简单的方法设置进入.离开和列表的动效.那么对于数据元素本身的动效呢,比如: 数字和运算 颜色的显示 SVG 节点的位置 元素的大小和其他的属性 所有的原始数字都被事先存储起来,可以直接转换到数字.做到这一步,我们就可以结合 Vue 的响应式和组件系统,使用第三方库来实现切换元素的过渡状态. 状态动画和watcher 通过 watcher 我们能监听到任何数值属性的数值更新.可能听起来很抽象,所以让我们先来看看使用 T

PHP学习笔记——入门篇(1)——语法&变量

基础 PHP 语法 PHP 脚本可放置于文档中的任何位置. PHP 脚本以 <?php 开头,以 ?> 结尾: PHP 文件通常包含 HTML 标签以及一些 PHP 脚本代码. 注释:PHP 语句以分号结尾(;).PHP 代码块的关闭标签也会自动表明分号(因此在 PHP 代码块的最后一行不必使用分号). PHP 支持三种注释: //单行注释 #单行注释 /*多行注释*/ PHP 大小写敏感区分: 在 PHP 中,所有用户定义的函数.类和关键词(例如 if.else.echo 等等)都对大小写不

## vue学习笔记--简单父子组件--

## vue学习笔记 ### 组件之间的通讯1. 父组件到子组件```js //father <div> <son msg="父组件的信息写在这"></son> <son title="title"></son> <!--:title--> </div> <script> export default { data(){ return { title: '当传递一个变量过

vue学习笔记の实现select组件

通过腾讯训练营这几天的学习,初步实现了自定义的选择下拉框组件,其中,可以把下拉选项抽离出来作为子组件,整个组件为父组件,其主要由<div>.<input>.<custom-select>.<ul>.<li>等标签构成基本的选择组件页面结构.主要的功能项:输入框及button按钮,构成初次展现的页面,通过点击输入框按钮,下拉列表选择项出现,当点击选择项中的某一项内容时,输入框中会出现相应的内容,再点击输入框,下拉选择项列表隐藏.同时,通过父组件与子