可以使用对象解构来创建对作用域插槽数据的直接引用,而不是使用单个变量名。换句话说,可以使用 v-slot="{user}" 代替 v-slot="slotProps" ,然后可以直接使用 user 而不是 slotProps.user 。
所以,上面的例子可以这样重写
// app.vue <template> <current-user v-slot="{user}"> {{ user.firstName }} </current-user> </template>
还有几点要记住:
可以使用 v-bind 指令绑定多个值。
也可以将函数传递到作用域槽。许多库使用它来提供可重用的函数组件。
v-slot 的别名是 # 。因此,可以用 #header="data" 来代替 v-slot:header="data" 。还可以使用 #header 来代替 v-slot:header (前提:不是作用域插槽时)。对于默认插槽,在使用别名时需要 指定默认名称 。换句话说,需要这样写 #default="data" 而不是 #="data" 。
可以从 文档 中了解更多的细节,但这足以帮助你理解在本文剩下部分中讨论的内容。
你能用插槽做什么?
插槽不是为了一个目的而构建的,或者至少如果它们是,它们已经超越了最初的意图,成为做许多不同事物的强大工具。
可重用的模式
组件总是被设计为可重用的,但是某些模式对于使用单个“普通”组件来实施是不切实际的,因为为了自定义它,需要的 props 数量可能过多或者需要通过 props 传递大部分内容或其它组件。
插槽可用包裹外部的HTML标签或者组件,并允许其他HTML或组件放在具名插槽对应名称的插槽上。
对于的第一个例子,从简单的东西开始:一个按钮。假设咱们的团队正在使用 Bootstrap。使用Bootstrap,按钮通常与基本的 “btn” 类和指定颜色的类绑定在一起,比如 “btn-primary” 。你还可以添加 size 类,比如 'btn-lg' 。
为了简单起见,现在让我们假设你的应用使用 btn 、 btn-primary 和 btn-lg 。你不希望总是必须在按钮上写下这三个类,或者你不相信新手会记得写下这三个类。
在这种情况下,可以创建一个自动包含所有这三个类的组件,但是如何允许自定义内容? prop 不实用,因为允许按钮包含各种HTML,因此我们应该使用一个插槽。
<!-- my-button.vue --> <template> <button> <slot>Click Me!</slot> </button> </template>
现在我们可以在任何地方使用它,无论你想要什么内容
<!-- 使用 my-button.vue --> <template> <my-button> <img src="https://www.jb51.net/img/awesome-icon.jpg"> 我是小智! </my-button> </template>
当然,你可以选择比按钮更大的东西。 坚持使用Bootstrap,让我们看一个模态:
<!-- my-modal.vue --> <template> <div tabindex="-1" role="dialog"> <div role="document"> <div> <div> <slot></slot> <button type="button" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div> <slot></slot> </div> <div> <slot></slot> </div> </div> </div> </div> </template>
现在,使用它:
<!-- 使用 my-modal.vue --> <template> <my-modal> <template #header> <h5>大家最棒!</h5> </template> <template #body> <p>大家加油</p> </template> <template #footer> <em>大家好样的!</em> </template> </my-modal> </template>
上述类型的插槽用例显然非常有用,但它可以做得更多。
复用函数
Vue组件并不完全是关于HTML和CSS的。它们是用JavaScript构建的,所以也是关于函数的。插槽对于一次性创建函数并在多个地方使用功能非常有用。让我们回到模态示例并添加一个关闭模态的函数
<!-- my-modal.vue --> <template> <div tabindex="-1" role="dialog"> <div role="document"> <div> <div> <slot></slot> <button type="button" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div> <slot></slot> </div> <div> <slot :closeModal="closeModal"></slot> </div> </div> </div> </div> </template> <script> export default { //... methods: { closeModal () { // 关闭对话框时,需要做的事情 } } } </script>