Svelte 的 svelte/action 模块提供了一种机制,允许你在元素创建时执行特定的动作(actions),并且这些动作可以在元素从 DOM 中移除时进行清理。动作是与元素关联的函数,它们可以在元素被添加到 DOM 时运行,并且在元素被移除时执行一个销毁(destroy)方法。

使用动作(Action)

动作是当元素被创建时调用的函数。它们可以返回一个对象,该对象具有在元素从 DOM 中卸载后调用的 destroy 方法:

  1. <script>
  2. /** @type {import('svelte/action').Action} */
  3. function foo(node) {
  4. // 节点已挂载到 DOM
  5. return {
  6. destroy() {
  7. // 节点已从 DOM 中移除
  8. }
  9. };
  10. }
  11. </script>
  12. <div use:foo />

如果你使用 TypeScript,可以为动作提供类型定义,以确保正确的参数和返回值:

  1. <script lang="ts">
  2. import type { Action } from 'svelte/action';
  3. const foo: Action = (node) => {
  4. // 节点已挂载到 DOM
  5. return {
  6. destroy() {
  7. // 节点已从 DOM 中移除
  8. },
  9. };
  10. };
  11. </script>
  12. <div use:foo />

动作可以有参数,并且如果返回的对象包含 update 方法,那么每当参数发生变化时,就会在 Svelte 应用更新到标记后立即调用它。

  1. <script>
  2. /** @type {string} */
  3. export let bar;
  4. /** @type {import('svelte/action').Action<HTMLElement, string>} */
  5. function foo(node, bar) {
  6. // 节点已挂载到 DOM
  7. return {
  8. update(bar) {
  9. // `bar` 的值已更改
  10. },
  11. destroy() {
  12. // 节点已从 DOM 中移除
  13. }
  14. };
  15. }
  16. </script>
  17. <div use:foo={bar} />

动作属性(Attributes)

有时动作会发出自定义事件并应用自定义属性到它们应用的元素上。为了支持这一点,使用 [Action](/docs/svelte-action#types-action)[ActionReturn](/docs/svelte-action#types-actionreturn) 类型定义的动作可以有一个最后一个参数,Attributes

  1. <script>
  2. /**
  3. * @type {import('svelte/action').Action<HTMLDivElement, { prop: any }, { 'on:emit': (e: CustomEvent<string>) => void }>}
  4. */
  5. function foo(node, { prop }) {
  6. // 节点已挂载到 DOM
  7. //...逻辑
  8. node.dispatchEvent(new CustomEvent('emit', { detail: 'hello' }));
  9. return {
  10. destroy() {
  11. // 节点已从 DOM 中移除
  12. }
  13. };
  14. }
  15. </script>
  16. <div on:emit={handleEmit} use:foo={{ prop: 'someValue' }} />

类型定义

Action

动作是当元素被创建时调用的函数。你可以使用这个接口来类型化这样的动作。例如,定义一个动作,它只对 <div> 元素有效,并且可以选择性地接受一个参数,该参数具有默认值:

  1. export const myAction: Action<HTMLDivElement, { someProperty: boolean } | undefined> = (node, param = { someProperty: true }) => {
  2. // ...
  3. };

[Action](/docs/svelte-action#types-action)<HTMLDivElement>[Action](/docs/svelte-action#types-action)<HTMLDivElement, undefined> 都表示动作不接受参数。

你可以从函数返回一个包含 updatedestroy 方法的对象,并类型化它,以确定它具有哪些附加属性和事件。有关更多详细信息,请参见接口 [ActionReturn](/docs/svelte-action#types-actionreturn)

ActionReturn

动作可以返回一个包含此接口中定义的两个属性的对象。两者都是可选的:

  • update: 动作可以有一个参数。每当该参数发生变化时,此方法将被调用,紧接在 Svelte 应用更新到标记之后。[ActionReturn](/docs/svelte-action#types-actionreturn)[ActionReturn](/docs/svelte-action#types-actionreturn)<undefined> 都表示动作不接受参数。
  • destroy: 在元素被卸载后调用的方法。

此外,你可以指定动作在应用的元素上启用哪些附加属性和事件。这只是 TypeScript 类型定义,并在运行时没有效果。

  1. interface Attributes {
  2. newprop?: string;
  3. 'on:event': (e: CustomEvent<boolean>) => void;
  4. }
  5. export function myAction(node: HTMLElement, parameter: Parameter): ActionReturn<Parameter, Attributes> {
  6. // ...
  7. return {
  8. update: (updatedParameter) => {...},
  9. destroy: () => {...}
  10. };
  11. }

更多信息和使用示例,请访问官方文档:svelte/action - Svelte Actions

  1. interface ActionReturn<
  2. Parameter = undefined,
  3. Attributes extends Record<string, any> = Record<
  4. never,
  5. any
  6. >
  7. > {…}
  1. update?: (parameter: Parameter) => void;
  1. destroy?: () => void;