本页面介绍了 Svelte 如何管理 DOM,包括模板创建、属性管理、事件处理和绑定系统。它涵盖了根据状态变化高效更新 DOM 的运行时机制。有关组件生命周期的信息,请参阅 组件生命周期。
Svelte 采用直接 DOM 操作方法,而不是虚拟 DOM。在编译期间,Svelte 会分析组件并生成优化的 JavaScript,从而实现有针对性的 DOM 更新。DOM 管理系统由几个相互关联的子系统组成,它们协同工作以高效地渲染和更新组件。
来源: packages/svelte/src/internal/client/dom/elements/attributes.js packages/svelte/src/internal/client/dom/elements/events.js packages/svelte/src/internal/client/dom/elements/bindings/input.js
Svelte 将组件编译成使用优化模板字符串创建 DOM 元素的 JavaScript。这种方法可以实现高效的初始渲染和精确的更新。
模板使用 $.template() 函数创建,该函数将静态 HTML 字符串编译成可重用的片段工厂。调用此工厂时,它会创建可操作并插入到文档中的 DOM 节点。
来源: packages/svelte/src/compiler/phases/3-transform/client/visitors/Fragment.js87-122 packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js4
在创建模板后,Svelte 使用各种函数来遍历和操作 DOM
$.first_child() - 获取元素的第一个子节点$.sibling() - 获取同级元素$.child() - 获取子节点$.next() - 在初始化期间移动到下一个节点// Example of DOM traversal pattern
var fragment = root();
var main = $.sibling($.first_child(fragment), 2);
var h1 = $.child(main);
var text = $.child(h1, true);
来源: packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js8-10
Svelte 通过区分静态和动态内容来优化渲染
例如,在此模板中
var root = $.template(`<header><nav>...</nav></header> <main>...</main>`, 3);
静态元素创建一次,而动态内容则通过函数调用单独更新。
来源: packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client/index.svelte.js4 packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/fragment.js10-173
Svelte 提供了一个全面的系统来管理元素属性、属性以及类和样式等特殊情况。
$.set_attribute() 函数用于在 DOM 元素上设置属性。它处理各种特殊情况
src来源: packages/svelte/src/internal/client/dom/elements/attributes.js156-194 packages/svelte/src/internal/client/dom/elements/attributes.js268-450
类名和样式属性会得到特殊处理
$.set_class() - 处理类名属性更新、作用域样式的 CSS 哈希添加和类名指令$.set_style() - 管理样式属性更新和样式指令clsx() 实用函数有助于将各种类名值(字符串、对象、数组)转换为正确的类名字符串。
来源: packages/svelte/src/internal/client/dom/elements/class.js1-51 packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js156-271
Svelte 对特定元素有特殊处理
| 元素 | 特殊处理 |
|---|---|
<input> | 值、选中状态、文件、默认值 |
<textarea> | 值、子内容 |
<select> | 选项选择、选项值 |
<option> | 选中状态、值处理 |
| 自定义元素 | 属性与元素的属性、事件处理 |
例如,对于 <input> 元素,Svelte 会处理重置默认值以及根据绑定更改进行更新。
来源: packages/svelte/src/internal/client/dom/elements/attributes.js33-64 packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js176-211
Svelte 提供了一个复杂的事件处理系统,支持委托和正确的事件冒泡。
事件使用 $.create_event() 函数附加到元素上,该函数封装了事件处理程序以管理响应式上下文和事件冒泡。
来源: packages/svelte/src/internal/client/dom/elements/events.js49-88
为提高效率,Svelte 在可能的情况下使用事件委托。$.delegate() 函数注册要由更高级别处理的事件类型,从而减少了事件监听器的数量。
来源: packages/svelte/src/internal/client/dom/elements/events.js132-140 packages/svelte/src/internal/client/dom/elements/events.js147-284
Svelte 通过 $.handle_event_propagation() 函数谨慎地管理事件传播。该系统
来源: packages/svelte/src/internal/client/dom/elements/events.js147-284
Svelte 的绑定系统将 DOM 元素连接到组件状态,创建双向数据流。
对于文本输入、文本区域和其他具有 value 属性的元素,$.bind_value() 函数建立双向连接
来源: packages/svelte/src/internal/client/dom/elements/bindings/input.js11-85
复选框和单选按钮使用专门的绑定函数
$.bind_checked() - 用于简单的复选框绑定$.bind_group() - 用于复选框组和单选按钮组来源: packages/svelte/src/internal/client/dom/elements/bindings/input.js86-251
选择元素需要使用 $.bind_select_value() 和 $.select_option() 函数进行特殊处理,这些函数根据绑定的值管理选项的选取。
来源:packages/svelte/src/internal/client/dom/elements/bindings/select.js1-147
媒体元素(音频/视频)对诸如 currentTime、volume、paused 等属性具有专门的绑定。这些绑定通常使用动画帧或事件来同步元素状态与组件状态。
来源:packages/svelte/src/internal/client/dom/elements/bindings/media.js1-218
对于元素尺寸和窗口属性,Svelte 提供了专门的绑定函数。
$.bind_resize_observer() - 用于元素尺寸$.bind_window_scroll() - 用于窗口滚动位置$.bind_window_size() - 用于窗口尺寸这些函数使用适当的浏览器 API(如 ResizeObserver)进行高效更新。
来源:packages/svelte/src/internal/client/dom/elements/bindings/size.js1-118 packages/svelte/src/internal/client/dom/elements/bindings/window.js1-66
水合(Hydration)是将客户端 JavaScript 附加到服务器渲染的 HTML 的过程。Svelte 的水合系统可确保从服务器到客户端渲染的无缝过渡。
在水合期间
$.hydrating 标志来控制行为来源:packages/svelte/src/internal/client/dom/elements/attributes.js158-177 packages/svelte/src/internal/client/dom/elements/events.js26-47
某些元素在水合期间需要特殊处理。
Svelte 提供了像 $.remove_input_defaults() 和 $.replay_events() 这样的函数来处理这些情况。
来源:packages/svelte/src/internal/client/dom/elements/attributes.js33-64 packages/svelte/src/internal/client/dom/elements/events.js26-47
Svelte 的 DOM 管理系统是一套全面的实用程序,可高效地创建、更新和管理 DOM 元素。通过使用直接的 DOM 操作而非虚拟 DOM,Svelte 以最小的运行时代码实现了高性能。该系统仔细处理特殊情况、事件委托,并提供了一个强大的绑定系统,将 DOM 元素连接到组件状态。
Svelte 方法的主要优点是
这些功能使 Svelte 能够提供强大而轻量级的组件模型,最大限度地减少运行时开销,同时提供丰富的开发体验。