如何在Vue中使用更复杂的插槽

原创
03/28 17:08
阅读数 16

Vue.js是一个易于使用的Web应用程序框架,可用于开发交互式前端应用程序。

在本文中,我将介绍命名插槽和作用域插槽。

命名插槽

有时我们的模板中会有多个插槽。为了区分每个插槽,我们必须给它们命名。

我们可以使用name属性定义具有命名插槽的组件,如下所示:

Vue.component("layout", {  template: `    <div>      <header>            <slot name="header"></slot>      </header>      <main>              <slot></slot>      </main>      <footer>              <slot name="footer"></slot>      </footer>    </div>  `});

然后我们可以将上述组件一起使用,如下所示:

src/index.js:

Vue.component("layout", {  template: `  <div>    <header>          <slot name="header"></slot>    </header>    <main>            <slot></slot>    </main>    <footer>            <slot name="footer"></slot>    </footer>  </div>  `});
new Vue({ el: "#app"});

index.html:

<!DOCTYPE html><html>  <head>    <title>App</title>    <meta charset="UTF-8" />    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  </head>  <body>    <div id="app">      <layout>        <template v-slot:header>          <h1>Header</h1>        </template>        <p>Main</p>        <template v-slot:footer>          <p>Footer</p>        </template>      </layout>    </div>    <script src="src/index.js"></script>  </body></html>

填充具有header名称的插槽:

<template v-slot:header>   <h1>Header</h1></template>

填充具有footer名称的插槽:

<template v-slot:footer>   <p>Footer</p></template>

填充没有名称的插槽:

<p>Main</p>

我们还可以使用v-slot:default填充没有名字的默认插槽,如下所示:

<template v-slot:default>  <p>Main</p></template>

无论哪种方式,渲染出来的HTML都是相同的。

作用域插槽

我们可以使用作用域插槽来访问子组件中的数据。

为了使子组件中的数据在父组件中可用,我们可以使用v-bind指令。

一个简单的示例,从父级去获取子级组件数据如下:

src/index.js:

Vue.component("user", {  data() {    return {      user: {        firstName: "Joe",        lastName: "Smith"      }    };  },  template: `<p>    <slot v-bind:user="user"></slot>  </p>`});
new Vue({ el: "#app"});

index.html:

<!DOCTYPE html><html>  <head>    <title>App</title>    <meta charset="UTF-8" />    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  </head>  <body>    <div id="app">      <user>        <template v-slot:default="slotProps">          {{ slotProps.user.firstName }}        </template>      </user>    </div>    <script src="src/index.js"></script>  </body></html>

在上面的代码中,我们设置了子组件上的插槽数据:

<p>   <slot v-bind:user="user"></slot></p>

在根Vue实例中就可以使用user了。

然后在根模板中,我们可以这样使用user

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

通过slotProps访问用户的数据,slotProps可以访问子组件中的v-bind提供的所有数据。

单独默认插槽的缩写语法

如果只有一个默认插槽,那么我们可以直接在子组件上使用v-slot:defaultv-slot,如下所示:

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

或:

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

如果还有其他命名的插槽,则可能存在歧义,因此无法使用上述语法。

如果我们有多个插槽,那么我们必须老老实实编写如下内容:

src/index.js:

Vue.component("user", {  data() {    return {      user: {        firstName: "Joe",        lastName: "Smith"      }    };  },  template: `<p>    <slot v-bind:user="user" name='first-name'></slot>    <slot v-bind:user="user" name='last-name'></slot>  </p>`});
new Vue({ el: "#app"});

index.html:

<!DOCTYPE html><html>  <head>    <title>App</title>    <meta charset="UTF-8" />    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  </head>  <body>    <div id="app">      <user>        <template v-slot:first-name="slotProps">          {{ slotProps.user.firstName }}        </template>        <template v-slot:last-name="slotProps">          {{ slotProps.user.lastName }}        </template>      </user>    </div>    <script src="src/index.js"></script>  </body></html>

在上面的代码中,我们必须明确命名插槽,然后才能分别通过v-slot:first-name="slotProps"v-slot:last-name="slotProps"访问子组件的数据。

另外,我们将插槽内容包装在template中。

解构作用域插槽数据

我们可以使用解构赋值运算符来解构插槽作用域数据。

例如,我们可以按以下方式使用它:

src/index.js:

Vue.component("user", {  data() {    return {      user: {        firstName: "Joe",        lastName: "Smith"      }    };  },  template: `<p>    <slot v-bind:user="user" name='first-name'></slot>    <slot v-bind:user="user" name='last-name'></slot>  </p>`});
new Vue({ el: "#app"});

index.html:

<!DOCTYPE html><html>  <head>    <title>App</title>    <meta charset="UTF-8" />    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  </head>  <body>    <div id="app">      <user>        <template v-slot:first-name="{ user }">          {{ user.firstName }}        </template>        <template v-slot:last-name="{ user }">          {{ user.lastName }}        </template>      </user>    </div>    <script src="src/index.js"></script>  </body></html>

在上面的代码中,我们没有使用slotProps,而是将其更改为{ user }{ user }slotProps.user相同。

最后

我们可以使用命名插槽和作用域插槽创建多个插槽,并分别从父级的子级组件中去访问数据。

命名插槽可防止歧义,并允许我们使用多个插槽。

另外,我们可以在子组件中使用v-bind,然后在组件中使用slotProps从父组件访问子组件的数据。

本文分享自微信公众号 - 前端知否(qianduanzhifou)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
在线直播报名
返回顶部
顶部