Vue内容分发slot

风伟酱_5140

风伟酱_5140

2017-08-19

1946人浏览

原创

前面的话

  为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为 内容分发 (或 “transclusion” )。vue实现了一个内容分发 api,参照了当前 web 组件规范草案,使用特殊的 元素作为原始内容的插槽。本文将详细介绍vue内容分发slot

编译作用域

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

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

  message 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

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

<!-- 无效 -->
<child-component></child-component>

  假定someChildProperty是子组件的属性,上例不会如预期工作。父组件模板不应该知道子组件的状态

  如果要绑定作用域内的指令到一个组件的根节点,应当在组件自己的模板上做:

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

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

 

默认丢弃

  一般地,如果子组件模板不包含插口,父组件的内容将会被丢弃

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>测试内容</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

<p>
  <parent></parent></p><script></script><script>var childNode = {
  template: `  <p class="child">
    <p>子组件
    `,
};var parentNode = {
  template: `  <p class="parent">
    <p>父组件
    <child>
      <p>测试内容
    
    `,
  components: {    'child': childNode
  },
};// 创建根实例new Vue({
  el: '#example',
  components: {    'parent': parentNode
  }
})</script>

  如下图所示,所包含的

测试内容

被丢弃

 

匿名slot

  当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身

var childNode = {
  template: `  <p>
    </p><p>子组件</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/js/1492" title="jQuery纵向tab选项卡内容切换代码"><img
														src="https://img.php.cn/upload/jscode/000/000/001/59bf6c816a5ce574.jpg" alt="jQuery纵向tab选项卡内容切换代码" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/js/1492" title="jQuery纵向tab选项卡内容切换代码" class="overflowclass">jQuery纵向tab选项卡内容切换代码</a>
													<p class="overflowclass">jQuery纵向tab选项卡内容切换代码</p>
												</div>
												<a rel="nofollow" href="/xiazai/js/1492" title="jQuery纵向tab选项卡内容切换代码" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>
    <slot></slot>
  
  `,
};

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>测试内容</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

  如果出现多于1个的匿名slot,vue将报错

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot></slot>
    <slot></slot>
  
  `,
};

【默认值】

  最初在 标签中的任何内容都被视为备用内容,或者称为默认值。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容

  当slot存在默认值,且父元素在中没有要插入的内容时,显示默认值

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot><p>我是默认值</p></slot>
  
  `,
};
var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child></child>
  
  `,
  components: {
    'child': childNode
  },
};

  当slot存在默认值,且父元素在中存在要插入的内容时,则显示设置值

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot><p>我是默认值</p></slot>
  
  `,
};
var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>我是设置值</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

 

具名Slot

   元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot>头部默认值</slot>
    <slot>主体默认值</slot>
    <slot>尾部默认值</slot>
  
  `,
};

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>我是头部</p>
      <p>我是尾部</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

  仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的备用插槽。匿名slot只能作为没有slot属性的元素的插槽,有slot属性的元素如果没有配置slot,则会被抛弃

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot>主体默认值</slot>
    <slot></slot>
  
  `,
};

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>我是主体</p>
      <p>我是其他内容</p>
      <p>我是尾部</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

  

插入中,

我是其他内容

插入中,而

被丢弃

  如果没有默认的 slot,这些找不到匹配的内容片段也将被抛弃

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
    <slot>主体默认值</slot>
  

  `, };

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <p>我是主体</p>
      <p>我是其他内容</p>
      <p>我是尾部</p>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

  

我是其他内容

和

都被抛弃

 

作用域插槽

  作用域插槽是一种特殊类型的插槽,用作使用一个 (能够传递数据到) 可重用模板替换已渲染元素。

  在子组件中,只需将数据传递到插槽,就像将 props 传递给组件一样

<p>
  <slot></slot></p>

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

var childNode = {
  template: `  <p>
    </p><p>子组件</p>
      <slot></slot>
  
  `,
};
var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <template>
        <p>hello from parent</p>
        <p>{{ props.xxx }}</p>
      </template>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

  如果渲染以上结果,得到的输出是

【列表组件】

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

var childNode = {
  template: `  
        默认值   
  `,   data(){     return{       items:[         {id:1,text:'第1段'},         {id:2,text:'第2段'},         {id:3,text:'第3段'},       ]     }   } };

var parentNode = {
  template: `  <p>
    </p><p>父组件</p>
    <child>
      <template>
        <li>{{ props.text }}</li>
      </template>
    </child>
  
  `,
  components: {
    'child': childNode
  },
};

 

前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

2026.10.28

40

16

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

2026.10.28

20

15

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

2026.10.28

40

10

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

120

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

80

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

80

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

40

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

80

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

40

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Gradle Wrapper 使用与安全指南
Gradle Wrapper 使用与安全指南

共0课时 | 0人学习

Buffalo框架路由开发手册
Buffalo框架路由开发手册

共0课时 | 0人学习

nginx手册
nginx手册

共0课时 | 0人学习