vue 插槽

74 阅读3分钟

插槽

我对插槽的评价是好用且方便。因为有了插槽的存在,我们可以通过一定的手段在父组件改变或定义子组件渲染的内容,同时,我们抽离组件与渲染组件也可以更加灵活。举个例子:

1699840001537.png

掘金首页的顶部导航栏就可以抽离出一个组件,大体如下图所示,每个框中的内容均可使用插槽来自定义内容。

1699840001537(1).png

在组件中,我们只需要确定大体框架,对于具体渲染的内容可以在组件被调用时由父组件定义,或者组件中也可以设置默认渲染内容。由于vue插槽的特性,当插槽有默认内容且父组件未指定插槽内容时,插槽部分将自动渲染默认内容, 无论插槽有无默认内容,当父组件指定插槽内容时,都将会渲染父组件所指定的插槽内容。

默认插槽

默认插槽的使用很简单,接下来我将给出一个简单的例子。

//父组件
<slot-test>
  //插槽内容
  hahaha
</slot-test>
//子组件
<div>
  <slot></slot>//插槽渲染位置
</div>

最后渲染出来的DOM为

<div>hahaha</div>

虽然我的示例是以文本内容作为插槽内容,但是这并不意味着插槽的内容只能是文本,实际上插槽的内容可以是任意的合法模版内容。这也就意味着你可以在父组件直接定义子组件所渲染的DOM。

此外,由于插槽内容是在父组件定义的,自然而然的,我们可以使用插值语法来进行文本键入而不是使用父子组件传值,这也会更加方便我们对子组件内容的掌握。示例:

//父组件
<slot-test>
  //插槽内容
  //textH = “hahaha”  
  {{textH}}
</slot-test>
//子组件
<div>
  <slot></slot>//插槽渲染位置
</div>

最后渲染出来的DOM为

<div>hahaha</div>

熟练的使用插槽将会对我们的开发有非常大的帮助。

具名插槽

在某些场景,在一个子组件中会存在多个插槽,这种时候我们就需要某种方法来对插槽进行辨别。VUE 是否提供了某种方法处理这种场景呢,答案是有的,那就是具名插槽。具名插槽——具有名字的插槽,怎么让插槽带有名字呢?其实很简单,只需要在 slot 标签上添加一个特殊的 attribute name 即可。这时候我们需要使用到 VUE 的一个默认指令 v-slot ,简写成 # ,这个指令是用来在父组件中指定插槽名的。此外,在父组件指定插槽内容时,需要在外层包裹 template 标签,并在 template 上指定插槽的名字。具体使用方法如示例

//父组件
<slot-test>
  //插槽内容 
  <template #header>
    header
  </template>
  <template #default>
    default
  </template>
  <template #footer>
    footer
  </template>
</slot-test>
//子组件
<div> 
  <header> 
    <slot name="header"></slot> 
  </header> 
  <main>
    <slot></slot>
  </main>
  <footer> 
    <slot name="footer"></slot> 
  </footer>  
</div>

最后渲染的DOM

<div> 
  <header>header</header> 
  <main>default</main>
  <footer>footer</footer>  
</div>

对于默认插槽,当使用template包裹其插槽内容时,会默认它的名字为 default 。对于默认插槽与具名插槽混用时还有另一种写法,但是我不想用,因此这里我就不写了。我的看法是,如果使用了具名插槽,那就不要再与默认插槽混用了,老老实实为每一个插槽取个名字就好了。

作用域插槽

没怎么见过,先不写了。