阅读 113
教你轻松上手Vue插槽(slot)

教你轻松上手Vue插槽(slot)

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

1.插槽小栗子

在我们封装组件的时候,我们可能会遇到这种情况,这个组件的功能是我们需要的可是ui界面不是我们需要的

对于这种情况,就需要用到slot 插槽

来个简单的小栗子

子组件:(<navigation-link>的模板中可能会写为:)

<a v-bind:href="url" class="nav-link" > 
    <slot></slot> 
</a>
复制代码

父组件使用

<navigation-link url="/profile">
    Your Profile 
</navigation-link>
复制代码

当组件渲染的时候,<slot></slot> 将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 HTML:

<navigation-link url="/profile">
    <!-- 添加一个 Font Awesome 图标 --> 
    <span class="fa fa-user"></span> 
    Your Profile 
</navigation-link>
复制代码

甚至其它的组件:

<navigation-link url="/profile"> 
    <!-- 添加一个图标的组件 --> 
    <font-awesome-icon name="user"></font-awesome-icon> 
    Your Profile 
</navigation-link>
复制代码

但是 如果 <navigation-link>template 中没有包含一个 <slot> 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。

2.后备内容(我也喜欢叫做默认内容)

每次都为插槽添加内容也是麻烦的要死,在我们开发的时候也不可能都是每个功能都需要一样,而ui展示是完全不一样的,有人的地方就有需求,有需求才能更好的生产

后备内容应运而生:

子组件: submit-button.vue

<button type="submit"> 
    <slot>Submit</slot> 
</button>
复制代码

父组件使用:

现在当我在一个父级组件中使用 <submit-button> 并且不提供任何插槽内容时:

<submit-button></submit-button>
复制代码

后备内容“Submit”将会被渲染;

但是如果我们提供内容:

<submit-button> Save </submit-button>
复制代码

父组件提供的内容“Save”将会被渲染从而取代后备内容

3.具名插槽

有时我们需要多个插槽。例如对于一个带有如下模板的 <base-layout> 组件:

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

对于这样的情况, 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

<div class="container"> 
    <header> 
        <slot name="header"></slot>
    </header>
    <main> 
        <slot></slot> 
    </main> 
    <footer> 
        <slot name="footer"></slot> 
    </footer> 
</div>
复制代码

一个不带 name<slot> 出口会带有隐含的名字default

在向具名插槽提供内容的时候,我们可以在一个 <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>
复制代码

当然你也可以写的更加明确一些

<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>
复制代码

效果如下:

Here might be a page title

A paragraph for the main content.

And another one.

Here's some contact info

------------------------华丽的分割线----------------------------

顺嘴一提,这个颜色这个是掘金的样式导致的,别误会了哈

注意 v-slot 只能添加在 <template> 上 !!!!!!!!!!!

4.作用域插槽

有时让插槽内容能够访问子组件中才有的数据是很有用的。

但是 我们子组件在父组件中进行渲染的时候,对插槽进行提供的数据只能是父组件的

就像这样

子组件:

<span> 
    <slot>{{ user.lastName }}</slot>
</span>
复制代码

我们可能想换掉备用内容:

像这样:

<current-user> {{ user.firstName }} </current-user>
复制代码

但是这里插槽渲染的 user.firstName 却是父组件下面的 user.firstName 而不是 子组件下的,为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 <slot> 元素的一个 attribute 绑定上去:

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

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

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

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

当然 v-slot:default === v-slot 也是可以的

但是在多个的是 就需要 v-slot:default 而不是 v-slot

注意默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确

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

<current-user> 
    <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> 
    <template v-slot:other="otherSlotProps"> {{ otherSlotProps.user.firstName }} </template> 
</current-user>
复制代码

5.具名插槽的缩写

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (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>
复制代码

然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

<!-- 这样会触发一个警告 --> 
<current-user #="{ user }"> {{ user.firstName }} </current-user>
复制代码

如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:

<current-user #default="{ user }"> {{ user.firstName }} </current-user>
复制代码

总结

我们学会了 solt的各种使用方式

  • 默认插槽
  • 具名插槽
  • 作用域插槽
  • 具名插槽缩写

喜欢的点个赞吧!! 求求了

文章分类
前端
文章标签