分分钟玩转Vue.js组件(二)(2)

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发,Vue.js 实现了一个内容分发 API,使用特殊的 <slot> 元素作为原始内容的插槽。

如果不理解这段话,可以先跳过,你只要知道<slot>元素是一个内容插槽。

单个Slot

下面的代码在定义my-component组件的模板时,指定了一个<slot></slot>元素。

<div> <my-component> <h1>Hello Vue.js!</h1> </my-component> <my-component> </my-component> </div> <template> <div> <h2>This is a component!</h2> <slot>如果没有分发内容,则显示slot中的内容</slot> <p>Say something...</p> </div> </template> <script src="https://www.jb51.net/js/vue.js"></script> <script> Vue.component('my-component', { template: '#myComponent' }) new Vue({ el: '#app' }) </script>

这段代码运行结果如下:

分分钟玩转Vue.js组件(二)

第一个<my-component>标签有一段分发内容<h1>Hello Vue.js!</h1>,渲染组件时显示了这段内容。

分分钟玩转Vue.js组件(二)

第二个<my-component>标签则没有,渲染组件时则显示了slot标签中的内容。

View Demo

指定名称的slot

上面这个示例是一个匿名slot,它只能表示一个插槽。如果需要多个内容插槽,则可以为slot元素指定name属性。

多个slot一起使用时,会非常有用。例如,对话框是HTML常用的一种交互方式。
在不同的运用场景下,对话框的头部、主体内容、底部可能是不一样的。

分分钟玩转Vue.js组件(二)

这时,使用不同名称的slot就能轻易解决这个问题了。

<template> <div> <div v-bind:class="{ 'dialog-active': show }"> <div> <div> <span @click="close"></span> </div> <slot></slot> <slot></slot> <slot></slot> </div> </div> <div></div> </div> </template> <script src="https://www.jb51.net/js/vue.js"></script> <script> Vue.component('modal-dialog', { template: '#dialog-template', props: ['show'], methods: { close: function() { this.show = false } } }) new Vue({ el: '#app', data: { show: false }, methods: { openDialog: function() { this.show = true }, closeDialog: function() { this.show = false } } }) </script>

在定义modal-dialog组件的template时,我们使用了3个slot,它们的name特性分别是header、body和footer。

在<modal-dialog>标签下,分别为三个元素指定slot特性:

<div> <modal-dialog v-bind:show.sync="show"> <header slot="header"> <h1>提示信息</h1> </header> <div slot="body"> <p>你想在对话框中放什么内容都可以!</p> <p>你可以放一段文字,也可以放一些表单,或者是一些图片。</p> </div> <footer slot="footer"> <button @click="closeDialog">关闭</button> </footer> </modal-dialog> <button @click="openDialog">打开对话框</button> </div>

对话框的标题内容、主体内容、底部内容,完全由我们自定义,而且这些内容就是一些简单的HTML元素!

View Demo

分分钟玩转Vue.js组件(二)

如果需要定制对话框的样式,我们只需要在<modal-dialog>上追加一个v-bind指令,让它绑定一个class。

<modal-dialog v-bind:show.sync="show" v-bind:class="dialogClass">

然后修改一下Vue实例,在data选项中追加一个dialogClass属性,然后修改openDialog()方法:

new Vue({ el: '#app', data: { show: false, dialogClass: 'dialog-info' }, methods: { openDialog: function(dialogClass) { this.show = true this.dialogClass = dialogClass }, closeDialog: function() { this.show = false } } })

View Demo

分分钟玩转Vue.js组件(二)

虽然我们在modal-dialog组件中定义了3个slot,但是在页面中使用它时,并不用每次都指定这3个slot。
比如,有时候我们可能只需要header和body:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwzzps.html