Skip to main content

svelte-template-syntax

Svelte 5 模板语法技能。当用户需要使用 {#if}/{#each}/{#await}/{#snippet} 等块级语法、{@render}/@{html} 等模板标签、bind:、use:/transition:/in:/out:/animate:、style:/class/class:、{@attach} 等指令,或理解属性、事件、文本表达式等基础模板语法时使用。

الانتقال إلى التثبيت

معلومات المصدر

المستودع
full-stack-skills/svelte-skills
آخر نشاط في المصدر
١١ سبتمبر ٢٠٢٦ في ١٣:٤٣
لغة SKILL.md المكتشفة
الصينية
النجوم
٣
التفرعات
٢

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
27 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
svelte-template-syntax
license
Apache-2.0
description
Svelte 5 模板语法技能。当用户需要使用 {#if}/{#each}/{#await}/{#snippet} 等块级语法、{@render}/@{html} 等模板标签、bind:、use:/transition:/in:/out:/animate:、style:/class/class:、{@attach} 等指令,或理解属性、事件、文本表达式等基础模板语法时使用。
# Svelte Template Syntax Reference (Svelte 5) 本技能覆盖 Svelte 5 模板语法,包括基础标记、块级表达式、模板标签、事件处理、属性绑定、style/class 指令、附件/动作、过渡和动画。 ## When to use this skill 当用户需要编写或理解 Svelte 组件中的模板语法,包括条件渲染、列表渲染、异步处理、片段复用、事件绑定、双向数据绑定、过渡动画等场景时使用本技能。 ## Critical: Basic Markup ### 元素标签 - 小写标签(`<div>`)= HTML 元素 - 大写/点号标签(`<Widget>`、`<my.stuff>`)= 组件 ### 属性绑定 ```svelte <!-- 布尔属性 --> <button disabled={!clickable}>...</button> <input required={false} /> <!-- 简写(同名字相同) --> <button {disabled}>...</button> <!-- 展开属性(顺序决定优先级:后写覆盖先写) --> <Widget {...props} a="b" /> <!-- 布尔属性:truthy 包含,falsy 排除 --> <div data-active={isActive}> <!-- true → 包含,false/null/undefined → 排除 --> ``` ### 事件处理 ```svelte <!-- onclick 是属性,不是指令 --> <button onclick={() => count++}>+</button> <input {onkeydown} /> <!-- 简写形式 --> <button {...handlerProps}> <!-- 展开形式 --> <!-- 事件委托:大多数事件委托到根节点,无需 stopPropagation --> <!-- 若需阻止:使用 svelte/events 的 on 函数 --> ``` ### 文本表达式 ```svelte <p>{expression}</p> <!-- null/undefined → 省略,其余转字符串 --> <p>Hello {name}!</p> <!-- 原始 HTML(注意 XSS) --> {@html rawContent} <!-- 转义花括号 --> <p>使用 &lbrace; 和 &rbrace;</p> ``` ## Critical: {#if ...} 条件渲染: ```svelte {#if count > 10} <p>big</p> {:else if count > 5} <p>medium</p> {:else} <p>small</p> {/if} ``` `{:else if}` 可以链式多次,`{:else}` 为最终 fallback。 ## Critical: {#each ...} 列表渲染: ```svelte {#each items as item} <li>{item.name}</li> {/each} <!-- 带索引 --> {#each items as item, i} <li>{i + 1}: {item.name}</li> {/each} <!-- 空列表 fallback --> {#each todos as todo} <p>{todo.text}</p> {:else} <p>No tasks!</p> {/each} ``` ### 带 key 的高效更新 ```svelte {#each items as item (item.id)} <li>{item.name}</li> {/each} ``` Key 必须是唯一标识(字符串/数字),用于 Svelte 高效 diff 和更新 DOM(插入/移动/删除而非整体重渲染)。 ### 解构和 rest ```svelte {#each items as { id, name, ...rest }} <li><span>{id}</span><MyComponent {...rest} /></li> {/each} {#each items as [id, ...values]} <li><span>{id}</span></li> {/each} ``` ### 渲染 N 次 ```svelte {#each { length: 8 }, rank} <div class:black={(rank) % 2 === 1}></div> {/each} ``` ## Critical: {#key ...} 当表达式变化时销毁并重建内容(触发过渡动画): ```svelte {#key value} <div transition:fade>{value}</div> {/key} ``` ## Critical: {#await ...} Promise 异步状态分支: ```svelte {#await promise} <p>loading...</p> {:then value} <p>result: {value}</p> {:catch error} <p>error: {error.message}</p> {/await} <!-- 简洁形式(无 pending UI) --> {#await promise then value} <p>{value}</p> {/await} <!-- 仅错误处理 --> {#await promise catch error} <p>{error.message}</p> {/await} ``` ### 懒加载组件 ```svelte {#await import('./Heavy.svelte') then { default: Component }} <Component /> {/await} ``` ### await 表达式(Svelte 5.36+ experimental) ```svelte <!-- 需 svelte.config.js 中启用 experimental.async --> <svelte:boundary> <p>{await fetchData()}</p> {#snippet pending()}<p>loading</p>{/snippet} </svelte:boundary> ``` 特性:同步更新、并发执行(独立 `await`)、`<svelte:boundary>` pending snippet、`fork()` API。 ## Critical: {#snippet ...} 可复用的标记片段,取代 Svelte 4 的 Slots: ```svelte {#snippet card(item)} <div class="card"> <h3>{item.title}</h3> <p>{item.body}</p> </div> {/snippet} {@render card(item)} ``` ### Snippet 作用域 Snippet 可以引用外部变量(script 变量或 `{#each}` 块级变量),并对**同一词法作用域**的兄弟/子节点可见: ```svelte {#each items as item} {#snippet itemCard()} <div>{item.name}</div> <!-- 引用 item --> {/snippet} {@render itemCard()} {/each} ``` ### 显式 vs 隐式 prop ```svelte <!-- 隐式 prop(推荐)--> <Table {data}> {#snippet header()} <th>Name</th> {/snippet} </Table> <!-- 显式 prop --> <Table {data} header={myHeader} /> ``` ### 隐式 children 组件标签内的非 snippet 内容自动成为 `children` snippet: ```svelte <Button>click me</Button> <!-- Button.svelte --> <script> let { children } = $props(); </script> <button>{@render children()}</button> ``` ### 可选 snippet ```svelte {@render children?.()} <!-- 可选链 --> {#if children}{:else}fallback{/if} <!-- #if fallback --> ``` ### Snippet 类型定义 ```svelte <script lang="ts"> import type { Snippet } from 'svelte'; let { row }: { row: Snippet<[Item]> } = $props(); </script> ``` ### 导出 snippet(5.5+) ```svelte <script module> export { mySnippet }; </script> {#snippet mySnippet()} <div>content</div> {/snippet} ``` ### 程序化创建(createRawSnippet) ```ts import { createRawSnippet } from 'svelte'; const greet = createRawSnippet<[string]>((name) => ({ render: () => `<p>Hello, ${name}!</p>` })); ``` ## Critical: {@render ...} 渲染 snippet: ```svelte {@render snippetName(args)} {@render children?.()} <!-- 可选链安全调用 --> {@render (cond ? a : b)()} <!-- 任意表达式 --> ``` ## Critical: {@html ...} 插入原始 HTML(**注意 XSS 风险**): ```svelte {@html rawHtml} ``` - `{expression}` 自动转义 HTML 实体 - `{@html expression}` 直接插入原始 HTML,需确保内容可信 - 必须是**完整独立** HTML(不能跨 `{@html}` 拼接标签) - 不受 scoped 样式影响 — 用 `:global` 包裹 ## Critical: {@attach ...} 元素挂载时运行的函数(Svelte 5.29+),取代 `use:` action: ```svelte <script> /** @type {import('svelte/attachments').Attachment} */ function tooltip(node) { const tip = createTip(node); return { destroy() { tip.destroy(); } }; } </script> <button {@attach tooltip()}>hover</button> ``` ### 带参数的 Attachment Factory ```svelte function tooltip(content) { return (node) => { const tip = createTip(node, { content }); return { destroy() { tip.destroy(); } }; }; } <button {@attach tooltip(content)}>hover</button> ``` ### 条件 Attachment ```svelte <div {@attach enabled && myAttachment}>...</div> ``` ### 内联 Attachment ```svelte <canvas {@attach (canvas) => { const ctx = canvas.getContext('2d'); $effect(() => { ctx.fillStyle = color; /* ... */ }); }}></canvas> ``` ### 重新运行行为 `{@attach foo(bar)}` 在 `foo` 或 `bar` 变化时**完整重建**(与 action 不同)。 ### 从 Action 转换 ```js import { fromAction } from 'svelte/attachments'; const attach = fromAction(myAction); ``` ## Critical: bind: 指令 数据从子级回流到父级: ```svelte <!-- 简写 --> <input bind:value /> <input bind:value={value} /> ``` ### Function Bindings(5.9+) ```svelte <input bind:value={ () => value, (v) => value = v.toLowerCase() } /> ``` ### 完整 bind: 列表 | 指令 | 元素 | 类型 | |------|------|------| | `bind:value` | input/textarea/select | 双向 | | `bind:checked` | input[type=checkbox] | 双向 | | `bind:indeterminate` | input[type=checkbox] | 双向 | | `bind:group` | radio/checkbox 组 | 双向 | | `bind:files` | input[type=file] | 双向 | | `bind:open` | details | 双向 | | `bind:value` | select multiple | 数组 | | `bind:currentTime/paused/volume/muted/playbackRate` | audio/video | 双向 | | `bind:duration/buffered/seeking/ended/readyState/played` | audio/video | 只读 | | `bind:videoWidth/Height` | video | 只读 | | `bind:naturalWidth/Height` | img | 只读 | | `bind:innerHTML/innerText/textContent` | contenteditable | 双向 |
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub