基本标记
Svelte 组件内的标记可以被视为 HTML++。
¥Markup inside a Svelte component can be thought of as HTML++.
标签(Tags)
¥Tags
小写标签(如 <div>
)表示常规 HTML 元素。大写标记或使用点符号的标记(例如 <Widget>
或 <my.stuff>
)表示组件。
¥A lowercase tag, like <div>
, denotes a regular HTML element. A capitalised tag or a tag that uses dot notation, such as <Widget>
or <my.stuff>
, indicates a component.
<script>
import Widget from './Widget.svelte';
</script>
<div>
<Widget />
</div>
元素属性(Element attributes)
¥Element attributes
默认情况下,属性的工作方式与其 HTML 对应项完全相同。
¥By default, attributes work exactly like their HTML counterparts.
<div class="foo">
<button disabled>can't touch this</button>
</div>
与 HTML 中一样,值可以不加引号。
¥As in HTML, values may be unquoted.
<input type=checkbox />
属性值可以包含 JavaScript 表达式。
¥Attribute values can contain JavaScript expressions.
<a href="page/{p}">page {p}</a>
或者它们可以是 JavaScript 表达式。
¥Or they can be JavaScript expressions.
<button disabled={!clickable}>...</button>
如果布尔属性的值为 truthy,则将其包含在元素中,如果值为 falsy,则将其排除。
¥Boolean attributes are included on the element if their value is truthy and excluded if it’s falsy.
除非其他属性的值为 nullish(null
或 undefined
),否则将包含所有其他属性。
¥All other attributes are included unless their value is nullish (null
or undefined
).
<input required={false} placeholder="This input field is not required" />
<div title={null}>This div has no title attribute</div>
引用单数表达式不会影响值的解析方式,但在 Svelte 6 中,它会导致值被强制转换为字符串:
¥[!NOTE] Quoting a singular expression does not affect how the value is parsed, but in Svelte 6 it will cause the value to be coerced to a string:
> <button disabled="{number !== 42}">...</button>
> ```
当属性名称和值匹配(`name={name}`)时,可以将它们替换为 `{name}`。
¥When the attribute name and value match (`name={name}`), they can be replaced with `{name}`.
```svelte
<button {disabled}>...</button>
<!-- equivalent to
<button disabled={disabled}>...</button>
-->
组件属性(Component props)
¥Component props
按照惯例,传递给组件的值被称为属性或属性,而不是属性,这是 DOM 的一个功能。
¥By convention, values passed to components are referred to as properties or props rather than attributes, which are a feature of the DOM.
与元素一样,name={name}
可以用 {name}
简写替换。
¥As with elements, name={name}
can be replaced with the {name}
shorthand.
<Widget foo={bar} answer={42} text="hello" />
扩展属性允许将许多属性或属性一次传递到元素或组件。
¥Spread attributes allow many attributes or properties to be passed to an element or component at once.
一个元素或组件可以具有多个散布属性,这些属性散布在常规属性中。
¥An element or component can have multiple spread attributes, interspersed with regular ones.
<Widget {...things} />
事件(Events)
¥Events
通过向以 on
开头的元素添加属性,可以监听 DOM 事件。例如,要监听 click
事件,请将 onclick
属性添加到按钮:
¥Listening to DOM events is possible by adding attributes to the element that start with on
. For example, to listen to the click
event, add the onclick
attribute to a button:
<button onclick={() => console.log('clicked')}>click me</button>
事件属性区分大小写。onclick
监听 click
事件,onClick
监听 Click
事件,这是不同的。这可确保你可以监听包含大写字符的自定义事件。
¥Event attributes are case sensitive. onclick
listens to the click
event, onClick
listens to the Click
event, which is different. This ensures you can listen to custom events that have uppercase characters in them.
因为事件只是属性,所以适用与属性相同的规则:
¥Because events are just attributes, the same rules as for attributes apply:
你可以使用简写形式:
<button {onclick}>click me</button>
¥you can use the shorthand form:
<button {onclick}>click me</button>
你可以传播它们:
<button {...thisSpreadContainsEventAttributes}>click me</button>
¥you can spread them:
<button {...thisSpreadContainsEventAttributes}>click me</button>
从时间上讲,事件属性始终在绑定事件之后触发(例如,oninput
始终在更新到 bind:value
之后触发)。在底层,一些事件处理程序直接与 addEventListener
连接,而其他事件处理程序则是委托的。
¥Timing-wise, event attributes always fire after events from bindings (e.g. oninput
always fires after an update to bind:value
). Under the hood, some event handlers are attached directly with addEventListener
, while others are delegated.
使用 ontouchstart
和 ontouchmove
事件属性时,处理程序为 passive,以获得更好的性能。通过允许浏览器立即滚动文档,而不是等待查看事件处理程序是否调用 event.preventDefault()
,这极大地提高了响应能力。
¥When using ontouchstart
and ontouchmove
event attributes, the handlers are passive for better performance. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls event.preventDefault()
.
在极少数情况下,你需要防止这些事件默认值,你应该改用 on
(例如在操作内部)。
¥In the very rare cases that you need to prevent these event defaults, you should use on
instead (for example inside an action).
事件委托(Event delegation)
¥Event delegation
为了减少内存占用并提高性能,Svelte 使用了一种称为事件委托的技术。这意味着对于某些事件(请参阅下面的列表),应用根目录中的单个事件监听器负责运行事件路径上的任何处理程序。
¥To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event’s path.
有几个需要注意的陷阱:
¥There are a few gotchas to be aware of:
当你使用委托监听器手动分派事件时,请确保设置
{ bubbles: true }
选项,否则它将无法到达应用根¥when you manually dispatch an event with a delegated listener, make sure to set the
{ bubbles: true }
option or it won’t reach the application root直接使用
addEventListener
时,避免调用stopPropagation
,否则事件将无法到达应用根,处理程序将不会被调用。类似地,在应用根目录内手动添加的处理程序将在 DOM 中声明性地添加的处理程序(例如onclick={...}
)之前运行,无论是在捕获阶段还是冒泡阶段。出于这些原因,最好使用从svelte/events
而不是addEventListener
导入的on
函数,因为它将确保保留顺序并正确处理stopPropagation
。¥when using
addEventListener
directly, avoid callingstopPropagation
or the event won’t reach the application root and handlers won’t be invoked. Similarly, handlers added manually inside the application root will run before handlers added declaratively deeper in the DOM (with e.g.onclick={...}
), in both capturing and bubbling phases. For these reasons it’s better to use theon
function imported fromsvelte/events
rather thanaddEventListener
, as it will ensure that order is preserved andstopPropagation
is handled correctly.
以下事件处理程序被委托:
¥The following event handlers are delegated:
beforeinput
click
change
dblclick
contextmenu
focusin
focusout
input
keydown
keyup
mousedown
mousemove
mouseout
mouseover
mouseup
pointerdown
pointermove
pointerout
pointerover
pointerup
touchend
touchmove
touchstart
文本表达式(Text expressions)
¥Text expressions
JavaScript 表达式可以通过用大括号括起来作为文本包含在内。
¥A JavaScript expression can be included as text by surrounding it with curly braces.
{expression}
可以使用其 HTML 实体 字符串将大括号包含在 Svelte 模板中:{
为 {
、{
或 {
,}
为 }
、}
或 }
。
¥Curly braces can be included in a Svelte template by using their HTML entity strings: {
, {
, or {
for {
and }
, }
, or }
for }
.
如果你使用的是正则表达式 (RegExp
) 字面表示法,则需要将其括在括号中。
¥If you’re using a regular expression (RegExp
) literal notation, you’ll need to wrap it in parentheses.
<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>
<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>
表达式将被字符串化并转义以防止代码注入。如果你想渲染 HTML,请改用 {@html}
标签。
¥The expression will be stringified and escaped to prevent code injections. If you want to render HTML, use the {@html}
tag instead.
{@html potentiallyUnsafeHtmlString}
确保你转义传递的字符串或仅使用你控制的值填充它以防止 XSS 攻击
¥[!NOTE] Make sure that you either escape the passed string or only populate it with values that are under your control in order to prevent XSS attacks
注释(Comments)
¥Comments
你可以在组件内使用 HTML 注释。
¥You can use HTML comments inside components.
<!-- this is a comment! --><h1>Hello world</h1>
以 svelte-ignore
开头的注释将禁用下一个标记块的警告。通常,这些是可访问性警告;确保你出于充分的理由禁用它们。
¥Comments beginning with svelte-ignore
disable warnings for the next block of markup. Usually, these are accessibility warnings; make sure that you’re disabling them for a good reason.
<!-- svelte-ignore a11y-autofocus -->
<input bind:value={name} autofocus />
你可以添加以 @component
开头的特殊注释,当将鼠标悬停在其他文件中的组件名称上时会显示该注释。
¥You can add a special comment starting with @component
that will show up when hovering over the component name in other files.
`
<!--
@component
- You can use markdown here.
- You can also use code blocks here.
- Usage:
html