(10)svelte 教程:Slots
什么是 Slots
Slots 是 Svelte 框架中的一种特性,用于在组件中定义插槽,以便父组件可以向子组件传递任意的内容。这种机制使得组件更具灵活性和可复用性,因为你可以在组件内部插入动态的、定制的内容。Slots 主要有两种类型:默认插槽和命名插槽。
逐行解释代码
App.svelte
<script>import Modal from './Modal.svelte';let showModal = false;let toggleModal = () => {showModal = !showModal;};
</script>
-  import Modal from './Modal.svelte';- 从当前目录中导入名为 Modal的 Svelte 组件。
 
- 从当前目录中导入名为 
-  let showModal = false;- 声明一个名为 showModal的变量,初始值为false。这个变量用于控制Modal组件的显示与隐藏。
 
- 声明一个名为 
-  let toggleModal = () => { showModal = !showModal; };- 声明一个名为 toggleModal的箭头函数。这个函数的作用是切换showModal的值,使其在true和false之间切换。
 
- 声明一个名为 
<Modal {showModal} on:click={toggleModal}><!-- <h3>Add a New Ninja</h3> --><form><input type="text" placeholder='name'><input type="text" placeholder='belt colour'><button>Add Ninja</button></form><div slot="title"><h3>Add a New Ninja</h3></div>
</Modal>
-  <Modal {showModal} on:click={toggleModal}>- 使用 Modal组件,并传递两个属性:- {showModal}:将- showModal变量的当前值传递给- Modal组件,使其能够根据该值决定是否显示。
- on:click={toggleModal}:监听- Modal组件的- click事件,当该事件触发时,调用- toggleModal函数。
 
 
- 使用 
-  <!-- <h3>Add a New Ninja</h3> -->- 注释掉的标题行,用于说明表单的用途。
 
-  <form>- 创建一个表单元素,包含三个子元素: - <input type="text" placeholder='name'>:一个文本输入框,用于输入忍者的名字。
- <input type="text" placeholder='belt colour'>:一个文本输入框,用于输入忍者的腰带颜色。
- <button>Add Ninja</button>:一个提交按钮,标签为 “Add Ninja”。
 
 
- 创建一个表单元素,包含三个子元素: 
-  <div slot="title">- 创建一个 div元素,并通过slot="title"属性指定其为命名插槽的内容。
- <h3>Add a New Ninja</h3>:在- div内部,创建一个- h3元素,显示 “Add a New Ninja” 作为标题。
 
- 创建一个 
<main><button on:click={toggleModal}>Open Modal</button>
</main>
- <main>和- <button on:click={toggleModal}>Open Modal</button>- 创建一个 main元素,并在其内部创建一个按钮。
- on:click={toggleModal}:为按钮绑定- click事件,当按钮被点击时,调用- toggleModal函数,切换- showModal的值,从而控制- Modal的显示与隐藏。
 
- 创建一个 
Modal.svelte
<script>export let showModal = false;export let isPromo = false;
</script>
-  export let showModal = false;- 声明并导出一个名为 showModal的变量,初始值为false。这个变量由外部(父组件)传入,用于控制Modal组件的显示与隐藏。
 
- 声明并导出一个名为 
-  export let isPromo = false;- 声明并导出一个名为 isPromo的变量,初始值为false。这个变量用于控制Modal组件是否具有promo样式。
 
- 声明并导出一个名为 
{#if showModal}<!-- svelte-ignore a11y-click-events-have-key-events --><div class="backdrop" class:promo={isPromo} on:click|self><div class="modal"><slot name="title"><h3>Default Title</h3></slot><slot></slot></div></div>
{/if}
-  {#if showModal}- Svelte 的条件渲染语句。如果 showModal为true,则渲染内部的内容。
 
- Svelte 的条件渲染语句。如果 
-  <!-- svelte-ignore a11y-click-events-have-key-events -->- Svelte 的注释,忽略关于 a11y-click-events-have-key-events的可访问性警告。
 
- Svelte 的注释,忽略关于 
-  <div class="backdrop" class:promo={isPromo} on:click|self>- 创建一个 div元素,类名为backdrop,并根据isPromo的值动态添加promo类。
- on:click|self:为- div绑定- click事件,并添加- self修饰符。该修饰符确保只有在直接点击- div元素时才会触发事件处理函数,而不会在其子元素上触发。
 
- 创建一个 
-  <div class="modal">- 创建一个类名为 modal的div元素,用于显示模态框的内容。
 
- 创建一个类名为 
-  <slot name="title">- 创建一个命名插槽,名称为 title。如果父组件提供了对应的插槽内容,则渲染该内容;否则,渲染默认内容。
 
- 创建一个命名插槽,名称为 
-  <h3>Default Title</h3>- 在 slot内部,提供一个默认标题 “Default Title”。
 
- 在 
-  <slot></slot>- 创建一个默认插槽。如果父组件提供了插槽内容,则渲染该内容;否则,插槽内容为空。
 
以上代码展示了如何在 Svelte 中使用 Slots 来实现灵活的组件内容插入。通过命名插槽和默认插槽,父组件可以在子组件中插入任意内容,从而增强组件的可复用性和定制化能力。
App.svelte 完整代码
<script>import Modal from './Modal.svelte';let showModal = false;let toggleModal = () => {showModal = !showModal;};</script><Modal {showModal} on:click={toggleModal}><!-- <h3>Add a New Ninja</h3> --><form><input type="text" placeholder='name'><input type="text" placeholder='belt colour'><button>Add Ninja</button></form><div slot="title"><h3>Add a New Ninja</h3></div></Modal><main><button on:click={toggleModal}>Open Modal</button></main><style>main {text-align: center;padding: 1em;max-width: 240px;margin: 0 auto;}@media (min-width: 640px) {main {max-width: none;}}</style>
Modal.svelte 完整代码
<script>export let showModal = false;export let isPromo = false;
</script>{#if showModal}<!-- svelte-ignore a11y-click-events-have-key-events --><div class="backdrop" class:promo={isPromo} on:click|self><div class="modal"><slot name="title"><h3>Default Title</h3></slot><slot></slot></div></div>
{/if}<style>.backdrop{width: 100%;height: 100%;position: fixed;background: rgba(0,0,0,0.8);}.modal{padding: 10px;border-radius: 10px;max-width: 400px;margin: 10% auto;;text-align: center;background: white;}.promo .modal{background: crimson;color: white;}</style>