Vue slot的使用

插槽内容

ComponentA组件

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

引用

<component-a>
		Your Profile
</component-a>

渲染成,slot就会被<component-a>标签中的内容所替代

<template>
	<div>
		<a
		 v-bind:href="url"
		  class="nav-link"
		>
			Your Profile
		</a>
	</div>
</template>

编译作用域

<navigation-link url="/profile">
   {{ user.name }}
</navigation-link>

该插槽跟模板的其它地方一样可以访问相同的实例属性 (也就是相同的“作用域”),而不能访问 <navigation-link> 的作用域,如url

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  这里的 `url` 会是 undefined,因为 "/profile" 是
  _传递给_ <navigation-link> 的而不是
  在 <navigation-link> 组件*内部*定义的。
  -->
</navigation-link>

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的

后备内容

confirm-button组件

<button type="submit">
  <slot>确定</slot>
</button>

当使用组件,并且不提供任何插槽内容时

<confirm-button><confirm-button>

插槽内容将会使用后备内容

<button type="submit">
  确定
</button>

但是如果提供内容则使用提供的内容

<confirm-button>保存<confirm-button>
<button type="submit">
  保存
</button>

具名插槽-------------------------------------------重点

<base-layout> 组件

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

此时需要用到slot的name属性,可以定义多个插槽

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

一个不带 name 的 出口会带有隐含的名字“default”。

<base-layout>
  <template v-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 v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

具体使用的时候,需要在一个 <template> 元素上使用 v-slot 指令,并根据name值对应上参数

如果你希望更明确一些,仍然可以在一个 <template> 中包裹默认插槽的内容

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>

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

渲染成

<div class="container">
  <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>

注意 v-slot 只能添加在 <template> 上 (只有一种例外情况),这一点和已经废弃的 slot 特性不同。

作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的。例如,设想一个带有如下模板的 <current-user> 组件

<span>
  <slot>{{ user.lastName }}</slot>
</span>

我们想让它的后备内容显示用户的名,以取代正常情况下用户的姓,如下

<current-user>
  {{ user.firstName }}
</current-user>

然而上述代码不会正常工作,因为只有 <current-user> 组件可以访问到 user 而我们提供的内容是在父级渲染的。

为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 <slot> 元素的一个特性绑定上去:

<span>
  <slot :user="user">
    {{ user.lastName }}
  </slot>
</span>

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字

独占默认插槽的缩写语法

当被提供的内容只有默认插槽时,组件的标签才可以被当作插槽的模板来使用。这样我们就可以把 v-slot 直接用在组件上:

<current-user v-slot:default="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

这种写法还可以更简单。就像假定未指明的内容对应默认插槽一样,不带参数的 v-slot 被假定对应默认插槽:

<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>

只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>

  <template v-slot:other="otherSlotProps">
    ...
  </template>
</current-user>

具名插槽的缩写

即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:

<base-layout>
  <template #header>
    <h1>Here might be a page title</h1>
  </template>

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

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值