最常使用的Vue标签 教你 v-slot 插槽的作用与使用

31 篇文章 0 订阅
5 篇文章 0 订阅

在Vue的官方文档中,关于v-slot插槽的使用,介绍的不是非常清晰明确,插槽这个东西其实很好理解,当我们定义了一个Vue组件后,我们是不能在调用组件时在里面再定义其它的dom结构的:

<submit-button>
  <div>Save</div>
</submit-button>

上述这种结构是不合法的,如果 submit-button组件里 没有包含一个 <slot> 标签,则该组件起始标签和结束标签之间的任何内容都不会被显示,会被抛弃。那如果我们想在组件中再嵌入其它的dom结构该怎么办呢,这个时候就可以用到插槽这个功能了。在react同样具备这个功能,只不过他不向Vue那样封的这么彻底,给你几个明明白白的属性供你去使用,而是更贴近原生:

<!-- HTML -->
<Range>
    <Text>插槽</Text>
    <Text>react native</Text>
</Range>
// JSX语法
export default class Range extends Component {

  constructor(props) {
    super(props)
  }

  render() {
    return (
      <View style={styles.body}>
          {this.props.children}
      </View>
    )
  }

在react中是通过this.props.children这个属性来拿到组件中定义的dom结构,并在组件中定义位置去渲染。看到react的这个示例后,对你了解Vue的插槽应该能起到一定的帮助。

简单的说,插槽就是让你能够在组件标签中再定义其它的DOM结构。

插槽内容

插槽内可以包含任何模板代码,包括 HTML或者其它组件:

<!-- 添加HTML内容 -->
<touch-bar>
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  点击这里
</touch-bar>

<!-- 添加其它组件 -->
<touch-bar>
  <!-- 添加一个按钮的组件 -->
  <touch-button name="user"></touch-button>
  点击这里
</touch-bar>

编译作用域

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

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

在上面代码中,该插槽跟模板的其它地方一样可以访问相同的实例属性 (也就是相同的“作用域”)user.name,而不能访问 <navigation-link> 的作用域。例如 url 是访问不到的:

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
</navigation-link>

这里的 `url` 会是 undefined,因为 "/profile" 是传递给<navigation-link>组件的而不是在 <navigation-link> 组件标签内部定义的。
 

插槽的默认内容

有时为一个插槽设置具体的后备 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。例如在一个 <submit-button> 组件中,我们可能希望这个 <button> 内绝大多数情况下都渲染文本“Submit”。为了将“Submit”作为后备内容,我们可以将它放在 <slot> 标签内:

<button type="submit">
  <slot>Submit</slot>
</button>

现在当我在一个父级组件中使用 <submit-button> 并且不提供任何插槽内容时,后备内容“Submit”将会被渲染,但是如果我们提供内容,则这个提供的内容将会被渲染从而取代后备内容:

<!-- 不提供内容 -->
<submit-button></submit-button>

<!-- 提供内容 -->
<submit-button>
  Save
</submit-button>

具名插槽

有时我们在一个组件需要多个插槽,每个插槽被用在组件的不同的位置,对于这样的情况,<slot> 元素有一个特殊的特性:name这个特性可以用来定义额外的插槽的名称,一个不带 name 的 <slot> 会默认带有隐含的属性“default”:

<!-- 组件定义 -->
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

那么我们该如何使用呢?在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

<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>

注意: v-slot 只能添加在一个 <template> 上

作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的,这就正好解决了上面所说的编译作用域的问题。例如,设想一个带有如下模板的 <current-user> 组件,我们想让它的后备内容显示用户的名,以取代正常情况下用户的姓,如下:

<!-- current-user组件定义 -->
<span>
  <slot>{{ user.lastName }}</slot>
</span>

<!-- 使用current-user组件 -->
<current-user>
  {{ user.firstName }}
</current-user>

上述代码不会正常工作,因为只有父级中 <current-user> 组件可以访问到 user.firstName ,我们提供的内容是在父级渲染的,所以在<current-user>组件中定义的插槽拿不到user.lastName

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

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

在父级作用域中,我们还可以给<current-user>中的 v-slot 给定一个值来定义插槽 prop 的名字:

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

以上就是关于Vue插槽的讲述!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值