在组件模板中,添加ng-content标签,让你希望投影的内容出现在其中。ng-content标签可以理解为插槽。

注意:

  1. ng-content标签必须是空标签,如该标签有内容,会报编译错误,而Vueslot插槽不会(可对比学习)。

  2. ng-content标签是一个占位符,它不会创建真正的 DOM 元素。其自定义属性将被忽略。

单插槽内容投影

组件模板只含有一个<ng-content></ng-content>标签

<!-- 子组件 app-son 的模板 -->
<div>
	<header>头部</header>
    <ng-content></ng-content>
    <footer>底部</footer>
</div>

投影的内容可以是文本、一段HTML、也可以是组件。投影的内容将出现在子组件ng-content标签的位置。

<!-- 父组件 app-father 的模板 -->
<div>
	<app-son>我是投影的文本内容</app-son>		<!-- 投影内容是文本 -->
	<app-son>
		<h1>我是投影的h1标签</h1>	<!-- 投影内容是HTML -->
	</app-son>
	<app-son>
		<app-other></app-other>		<!-- 投影内容是其他组件 -->
	</app-son>
</div>

多插槽内容投影

组件模板含有多个<ng-content></ng-content>标签。

为了区分投影的内容可以投影到对应ng-content标签,需要使用ng-content标签上的select属性作为识别。

select属性支持标签名、属性、CSS 类和 :not 伪类的任意组合。

不添加select属性的ng-content标签将作为默认插槽。所有为匹配的投影内容都会投影在该ng-content的位置。

<!-- 子组件 app-son 的模板 -->
<div>
	<header>头部</header>
    <ng-content select="[property]"></ng-content>
    <ng-content select="h3"></ng-content>
    <ng-content select=".active"></ng-content>
    <ng-content select="#hello"></ng-content>
    <ng-content></ng-content>		<!-- 默认插槽 -->
    <footer>底部</footer>
</div>

投影内容会根据ng-content标签上的select属性投影在指定的位置。

<!-- 父组件 app-father 的模板 -->
<div>
	<app-son>
		<h3>h3标签</h3>
  		<div property>带property属性</div>
  		<div id="hello">id为hello</div>
  		<div class="active">class包含active类</div>
	</app-son>
</div>

以上投影内容都是select属性指定的直接子节点,如果用div标签包裹h3标签,让h3标签不是select="h3"指定的直接子节点。

<!-- 父组件 app-father 的模板 -->
<div>
	<app-son>
		<div>
			<h3>h3标签</h3>
		</div>
  		<div property>带property属性</div>
  		<div id="hello">id为hello</div>
  		<div class="active">class包含active类</div>
	</app-son>
</div>

我们发现h3标签的投影内容出现的位置发生了变化,出现在不带select属性的ng-content标签上,即默认插槽上。假如没有默认插槽,h3标签的投影内容将不显示。

我们可以设置 ngProjectAs 属性的值与select属性的值相匹配,来处理h3标签投影内容的位置不正确的情况(即投影内容不是作为直接子节点,而是作为非直接子节点的情况)。

<!-- 父组件 app-father 的模板 -->
<div>
	<app-son>
		<div ngProjectAs="h3">
			<h3>h3标签</h3>
		</div>
  		<div property>带property属性</div>
  		<div id="hello">id为hello</div>
  		<div class="active">class包含active类</div>
	</app-son>
</div>

设置 ngProjectAs 属性后,h3标签投影内容的位置回复正常。