zl程序教程

您现在的位置是:首页 >  前端

当前栏目

【Vue】理解<slot>插槽及其slot、slot-scope、v-slot指令的使用

Vue 理解 及其 指令 Scope slot 插槽 使用
2023-09-11 14:14:50 时间

什么是插槽

Vue本身实现了一套完善的内容分发的机制,使用元素作为内容分发的出口,也就是插槽。插槽内的模板、HTML代码以及组件会被渲染。

<!-- Example组件的定义 -->
<h1>
  <slot></slot>
</h1>

<Child>
  <p>我是插槽内容</p>
</Child>

如果组件本身没有元素作为出口,那么组件包含的内容都会被舍弃

<!-- Example组件的定义 -->
<h1></h1>

<Child>
  <!-- 被舍弃,不渲染 -->
  <p>我是插槽内容</p>
</Child>

默认插槽/匿名插槽(default slot)

上面例子中的没有显式声明name属性,就是默认插槽,其name的属性值默认为‘default’。如果向插槽传入数据时没有指明插槽名,就会传入默认插槽

具名插槽

具名插槽就是带有name属性的。在很多情况下,需要向多个插槽传入内容,此时就需要用到具名插槽。

作用域插槽

有时父组件需要访问插槽里的作用域,此时可以通过作用域插槽(v-slot和slot-scope)访问插槽的作用域对象,它由插槽上定义的特性值组成。

插槽默认值(后备内容)

<!-- Example组件的定义 -->
<h1>
  <slot>我是默认值</slot>
</h1>

<!-- 会渲染成<h1>我是默认值</h1> -->
<Child>
</Child>

<!-- 会渲染成<h1><p>我是新内容</p></h1> -->
<Child>
  <p>我是新内容</p>
</Child>

slot和slot-scope(3.0版本之后移除),可以通过vue-V查看vue版本

slot用于绑定传入内容的插槽,slot-scope获取插槽的作用域对象

v-slot(2.6版本之后加入)

结合上述两个指令的新指令:

  • v-slot:slotName绑定传入的插槽,缩写为#slotName 等价于slot=“slotName”
  • v-slot:slotName=“scope”,获取插槽的作用域对象并赋值给scope,等价于slot-scope=“scope”。同时可以使用ES6的解构语法获取指定的特性v-slot=“{
    footer }”
  • 当插槽为默认插槽时,v-slot可以不带修饰符,直接在组件上使用,并且将默认插槽的作用域赋给v-slot声明的变量
  • 最重要的一个特性就是可以直接在组件上声明获取插槽组件的作用域对象

slot-scope与v-slot的新老指令的使用对比

1. 默认文本插槽

<!-- 默认文本插槽 -->
<!-- old -->
<foo>
  <template slot-scope="{ msg }">
    {{ msg }}
  </template>
</foo>

<!-- new -->
<foo v-slot="{ msg }">
  {{ msg }}
</foo>

2. 默认元素插槽

<!-- 默认元素插槽 -->
<!-- old -->
<foo>
  <div slot-scope="{ msg }">
    {{ msg }}
  </div>
</foo>

<!-- new -->
<foo v-slot="{ msg }">
  <div>
    {{ msg }}
  </div>
</foo>

3. 嵌套默认插槽

<!-- 嵌套默认插槽 -->
<!-- old -->
<foo>
  <bar slot-scope="foo">
    <baz slot-scope="bar">
      <template slot-scope="baz">
        {{ foo }} {{ bar }} {{ baz }}
      </template>
    </baz>
  </bar>
</foo>

<!-- new -->
<foo v-slot="foo">
  <bar v-slot="bar">
    <baz v-slot="baz">
      {{ foo }} {{ bar }} {{ baz }}
    </baz>
  </bar>
</foo>

4. 具名插槽

<!-- 具名插槽 -->
<!-- old -->
<foo>
  <template slot="one" slot-scope="{ msg }">
    text slot: {{ msg }}
  </template>

  <div slot="two" slot-scope="{ msg }">
    element slot: {{ msg }}
  </div>
</foo>

<!-- new -->
<foo>
  <template v-slot:one="{ msg }">
    text slot: {{ msg }}
  </template>

  <template v-slot:two="{ msg }">
    <div>
      element slot: {{ msg }}
    </div>
  </template>
</foo>

5. 具名与默认混合嵌套插槽

<!-- 具名与默认混合嵌套插槽 -->
<!-- old -->
<foo>
  <bar slot="one" slot-scope="one">
    <div slot-scope="bar">
      {{ one }} {{ bar }}
    </div>
  </bar>

  <bar slot="two" slot-scope="two">
    <div slot-scope="bar">
      {{ two }} {{ bar }}
    </div>
  </bar>
</foo>

<!-- new -->
<foo>
  <template v-slot:one="one">
    <bar v-slot="bar">
      <div>{{ one }} {{ bar }}</div>
    </bar>
  </template>

  <template v-slot:two="two">
    <bar v-slot="bar">
      <div>{{ two }} {{ bar }}</div>
    </bar>
  </template>
</foo>

帮助理解

vue插槽(slot)详解