(12)svelte 教程:Dispatching Custom Events

(12)svelte 教程:Dispatching Custom Events

什么是 Dispatching Custom Events

在 Svelte 框架中,Dispatching Custom Events 是指组件可以触发自定义事件,这些事件可以由父组件或其他监听者来捕获和处理。这种机制允许组件之间进行更灵活的通信,不仅限于属性传递,还可以通过事件来传递信息和触发操作。通过这种方式,可以在组件中触发并处理特定的交互行为,提升组件的可复用性和模块化。

逐行解释代码

App.svelte
<script>
    import Modal from './Modal.svelte';
    import AddPersonForm from './AddPersonForm.svelte';

    let showModal = false;

    let toggleModal = () => {
      showModal = !showModal;
    };

    let people = [
      // { name: 'yoshi', beltColour: 'black', age: 25, id: 1 },
      // { name: 'mario', beltColour: 'orange', age: 45, id: 2 },
      // { name: 'luigi', beltColour: 'brown', age: 35, id: 3 }
    ];

    const handleClick = (e, id) => {
      people = people.filter(person => person.id != id);
      console.log(e);
    };

    const addPerson = (e) => {
      //console.log(e.detail);
      const person = e.detail;
      people = [person, ...people];
      showModal = false;
    };
</script>
  • import Modal from './Modal.svelte';

    • 从当前目录中导入名为 Modal 的 Svelte 组件。
  • import AddPersonForm from './AddPersonForm.svelte';

    • 从当前目录中导入名为 AddPersonForm 的 Svelte 组件。
  • let showModal = false;

    • 声明一个名为 showModal 的变量,初始值为 false。这个变量用于控制 Modal 组件的显示与隐藏。
  • let toggleModal = () => { showModal = !showModal; };

    • 声明一个名为 toggleModal 的箭头函数。这个函数的作用是切换 showModal 的值,使其在 truefalse 之间切换。
  • let people = [ /* ... */ ];

    • 声明一个名为 people 的数组,存储一组人物对象,每个对象包含 namebeltColourageid 属性。注释掉的部分是示例数据。
  • const handleClick = (e, id) => { /* ... */ };

    • 声明一个名为 handleClick 的箭头函数,当点击删除按钮时调用此函数,过滤掉数组中对应 id 的人物,并输出事件对象 e
  • const addPerson = (e) => { /* ... */ };

    • 声明一个名为 addPerson 的箭头函数,当触发 addPerson 事件时调用此函数,向 people 数组添加新人物,并隐藏模态框。
<Modal {showModal} on:click={toggleModal}>
    <AddPersonForm on:addPerson={addPerson} />
</Modal>
  • <Modal {showModal} on:click={toggleModal}>

    • 使用 Modal 组件,并传递两个属性:
      • {showModal}:将 showModal 变量的当前值传递给 Modal 组件,使其能够根据该值决定是否显示。
      • on:click={toggleModal}:监听 Modal 组件的 click 事件,当该事件触发时,调用 toggleModal 函数。
  • <AddPersonForm on:addPerson={addPerson} />

    • Modal 组件中使用 AddPersonForm 组件,并监听 addPerson 事件。当该事件触发时,调用 addPerson 函数。
<main>
    <button on:click={toggleModal}>Open Modal</button>
    {#each people as person (person.id)}
      <div>
        <h4>{person.name}</h4>
        {#if person.beltColour === 'black'}
          <p><strong>MASTER NINJA</strong></p>
        {/if}
        <p>{person.age} years old, {person.beltColour} belt.</p>
        <button on:click={(e) => handleClick(e, person.id)}>delete</button>
      </div>
    {:else}
      <p>There are no people to show...</p>
    {/each}
</main>
  • <main><button on:click={toggleModal}>Open Modal</button>

    • 创建一个 main 元素,并在其内部创建一个按钮。
    • on:click={toggleModal}:为按钮绑定 click 事件,当按钮被点击时,调用 toggleModal 函数,切换 showModal 的值,从而控制 Modal 的显示与隐藏。
  • {#each people as person (person.id)}

    • 使用 each 模板语句遍历 people 数组,渲染每个人物的详细信息。
      • key: person.id:为每个 person 元素设置唯一键值 id,以提高渲染性能。
  • <div> /* ... */ </div>

    • 为每个人物创建一个包含其详细信息的 div 容器。
      • <h4>{person.name}</h4>:显示人物的名字。
      • {#if person.beltColour === 'black'}:如果人物的腰带颜色是黑色,显示 “MASTER NINJA” 标识。
      • <p>{person.age} years old, {person.beltColour} belt.</p>:显示人物的年龄和腰带颜色。
      • <button on:click={(e) => handleClick(e, person.id)}>delete</button>:创建一个删除按钮,绑定点击事件,调用 handleClick 函数并传递事件对象和人物的 id
  • {:else} <p>There are no people to show...</p> {/each}

    • 如果 people 数组为空,则显示提示信息 “There are no people to show…”.
AddPersonForm.svelte
<script>
    import { createEventDispatcher } from 'svelte';

    let name;
    let beltColour;
    let age;
    let skills = [];

    const dispatch = createEventDispatcher();

    const handleSubmit = () => {
      const person = {
        name,
        beltColour,
        age,
        skills,
        id: Math.random()
      };
      dispatch('addPerson', person);
    };
</script>
  • import { createEventDispatcher } from 'svelte';

    • 从 Svelte 导入 createEventDispatcher 函数,用于创建事件调度器。
  • let name;

    • 声明一个名为 name 的变量,用于存储用户输入的名字。
  • let beltColour;

    • 声明一个名为 beltColour 的变量,用于存储用户选择的腰带颜色。
  • let age;

    • 声明一个名为 age 的变量,用于存储用户输入的年龄。
  • let skills = [];

    • 声明一个名为 skills 的数组,用于存储用户选择的技能。
  • const dispatch = createEventDispatcher();

    • 创建一个事件调度器 dispatch,用于触发自定义事件。
  • const handleSubmit = () => { /* ... */ };

    • 声明一个名为 handleSubmit 的箭头函数,当表单提交时调用此函数,创建一个包含名字、腰带颜色、年龄、技能和唯一 id 的人物对象,并触发名为 addPerson 的自定义事件,将人物对象作为事件数据传递出去。
<form on:submit|preventDefault={handleSubmit}>
    <input type="text" placeholder='name' bind:value={name}>
    <input type="number" placeholder='age' bind:value={age}>
    <label>Skills:</label>
    <input type="checkbox" bind:group={skills} value="fighting">fighting<br>
    <input type="checkbox" bind:group={skills} value="sneaking">sneaking<br>
    <input type="checkbox" bind:group={skills} value="running">running<br>
    <label>Belt colour:</label>
    <select bind:value={beltColour}>
      <option value="black">black</option>
      <option value="orange">orange</option>
      <option value="brown">brown</option>
      <option value="white">white</option>
    </select>
    <button>Add Ninja</button>
</form>
  • <form on:submit|preventDefault={handleSubmit}>

    • 创建一个表单元素,并绑定 submit 事件。当表单提交时调用 handleSubmit 函数,并通过 preventDefault 修饰符阻止默认的表单提交行为(即页面刷新)。
<input type="text" placeholder='name' bind:value={name}>
  • 创建一个文本输入框,用于输入名字。通过 bind:value 双向绑定,将用户输入的值赋给 name 变量。
<input type="number" placeholder='age' bind:value={age}>
  • 创建一个数字输入框,用于输入年龄。通过 bind:value 双向绑定,将用户输入的值赋给 age 变量。
<label>Skills:</label>
  • 创建一个标签,用于描述下面的技能选项。
<input type="checkbox" bind:group={skills} value="fighting">fighting<br>
<input type="checkbox" bind:group={skills} value="sneaking">sneaking<br>
<input type="checkbox" bind:group={skills} value="running">running<br>
  • 创建三个复选框,用于选择技能。通过 bind:group 将复选框的值绑定到 skills 数组中。选择或取消选择复选框会将对应的技能添加到或从 skills 数组中移除。
<label>Belt colour:</label>
  • 创建一个标签,用于描述下面的腰带颜色选项。
<select bind:value={beltColour}>
  <option value="black">black</option>
  <option value="orange">orange</option>
  <option value="brown">brown</option>
  <option value="white">white</option>
</select>
  • 创建一个选择框,用于选择腰带颜色。通过 bind:value 将选择框的值绑定到 beltColour 变量。
    • <option value="black">black</option>:创建一个选项,值为 “black”,显示为 “black”。
    • <option value="orange">orange</option>:创建一个选项,值为 “orange”,显示为 “orange”。
    • <option value="brown">brown</option>:创建一个选项,值为 “brown”,显示为 “brown”。
    • <option value="white">white</option>:创建一个选项,值为 “white”,显示为 “white”。
<button>Add Ninja</button>
  • 创建一个提交按钮,标签为 “Add Ninja”。点击此按钮会触发表单的 submit 事件,从而调用 handleSubmit 函数。

总结

通过以上代码示例,可以看到在 Svelte 中如何创建和触发自定义事件,从而实现组件之间的通信和数据传递。在 AddPersonForm.svelte 中,我们创建了一个事件调度器 dispatch,并在表单提交时触发名为 addPerson 的自定义事件,将新添加的人物数据传递给父组件 App.svelte。在 App.svelte 中,我们通过监听 addPerson 事件来处理新人物的添加操作,并动态更新 people 数组,从而实现页面的动态渲染和更新。

App.svelte 完整代码

<script>
	import Modal from './Modal.svelte';
	import AddPersonForm from './AddPersonForm.svelte';
  
	let showModal = false;
  
	let toggleModal = () => {
	  showModal = !showModal;
	};
  
	  let people = [
	  // { name: 'yoshi', beltColour: 'black', age: 25, id: 1 },
	  // { name: 'mario', beltColour: 'orange', age: 45, id: 2 },
	  // { name: 'luigi', beltColour: 'brown', age: 35, id: 3 }
	];
  
	const handleClick = (e, id) => {
	  people = people.filter(person => person.id != id);
	  console.log(e);
	};
  
	const addPerson = (e) => {
	  //console.log(e.detail);
	  const person = e.detail;
	  people = [person, ...people];
	  showModal = false;
	};
  </script>
  
  <Modal {showModal} on:click={toggleModal}>
	<AddPersonForm on:addPerson={addPerson} />
  </Modal>
  
  <main>
	<button on:click={toggleModal}>Open Modal</button>
	{#each people as person (person.id)}
	  <div>
		<h4>{person.name}</h4>
		{#if person.beltColour === 'black'}
		  <p><strong>MASTER NINJA</strong></p>
		{/if}
		<p>{person.age} years old, {person.beltColour} belt.</p>
		<button on:click={(e) => handleClick(e, person.id)}>delete</button>
	  </div>
	{:else}
	  <p>There are no people to show...</p>
	{/each}
  </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></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>

AddPersonForm.svelte 完整代码

<script>
    import { createEventDispatcher } from 'svelte';
  
    let dispatch = createEventDispatcher();
    let name;
    let beltColour;
    let age;
    let skills = [];
  
    const handleSubmit = () => {
      const person = {
        name, 
        beltColour,
        age, 
        skills,
        id: Math.random()  
      }
      dispatch('addPerson', person);
    };
  </script>
  
  <form on:submit|preventDefault={handleSubmit}>
    <input type="text" placeholder='name' bind:value={name}>
    <input type="number" placeholder='age' bind:value={age}>
    <!-- svelte-ignore a11y-label-has-associated-control -->
    <label>Skills:</label>
    <!-- <input type="checkbox" bind:checked={fighting}>fighting<br>
    <input type="checkbox" bind:checked={sneaking}>sneaking<br>
    <input type="checkbox" bind:checked={running}>running<br> -->
    <input type="checkbox" bind:group={skills} value="fighting">fighting<br>
    <input type="checkbox" bind:group={skills} value="sneaking">sneaking<br>
    <input type="checkbox" bind:group={skills} value="running">running<br>
    <!-- svelte-ignore a11y-label-has-associated-control -->
    <label>Belt colour:</label>
    <select bind:value={beltColour}>
      <option value="black">black</option>
      <option value="orange">orange</option>
      <option value="brown">brown</option>
      <option value="white">white</option>
    </select>
    <button>Add Ninja</button>
  </form>
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值