Поскольку я меняю проект React на SvelteKit, у меня возникла конкретная ситуация, которая меня очень заинтересовала.
Предположим, что у меня есть компонент в React, который получает объект columnsMockExample
в качестве реквизита, например, и использует HTML внутри объекта, как:
const columnsMockExample = [{name: 'Column 1', html: '<div>Inner HTML example</div>' }]
<ColumnsComponent columnsProp = {columnsMockExample}/>
Итак, в React мы могли бы отобразить этот объект, чтобы использовать его и показать каждый .html
внутри columnsMockExample
:
{props.columnsProp.map((columnFromMockExample) => columnFromMockExample.html)};
Итак, вот вопрос: поскольку SvelteKit имеет тег <script/>
помимо HTML, как я могу создать свой объект columnsMockExample
внутри тега SvelteKit<script/>
, поскольку это не JSX?
неправильный пример скрипта SvelteKit написан ниже:
<script>
const columnsMockExample = [{name: 'Column 1', html: '<div>Inner HTML example</div>' }]
</script>
Спасибо.
Если это чистый HTML (без кода, специфичного для Svelte, просто необработанный HTML), вы можете использовать директиву @html
:
<script>
const columnsMockExample = [{name: 'Column 1', html: '<div>Inner HTML example</div>' }]
</script>
{#each columnsMockExample as example}
{@html example.html}
{/each}
Документы: https://svelte.dev/docs#template-syntax-html
Если там есть компоненты Svelte или обработчики кликов и т. д., это не сработает. В этом случае вам нужно переписать код, используя компоненты и слоты (https://svelte.dev/docs#template-syntax-slot) и/или тег svelte:component
(https://svelte.dev/docs#template-syntax-svelte-component) — как именно, зависит от вашей цели.
Здесь можно использовать несколько разных подходов, каждый из которых немного отличается.
Используйте слоты, чтобы каждый столбец отображал ячейку и отображал целые строки через слот родительских компонентов. Пример можно увидеть в этом вопросе.
Определите отдельные компоненты, и вместо передачи HTML вы передаете класс компонента. На данный момент это немного неудобно, потому что компоненты не могут быть определены в одном и том же файле. Пример REPL
Ключевым моментом является динамическая визуализация компонентов с помощью <svelte:component />
и передача текущего значения столбца в качестве общеизвестного свойства, одинакового для всех компонентов ячейки.
Вместо того, чтобы использовать компоненты, визуализируйте HTML напрямую, используя {@html}
. Я рекомендую это точно нет, потому что это упрощает создание XSS-уязвимостей. Пример REPL
Ключевым моментом здесь является предоставление содержимого как функции значения столбца, например:
const columns = [
{ key: 'name', html: value => `<button>${value}</button>` },
{ key: 'age', html: value => `<em>${value}</em>` },
]
Таким образом, это может быть отображено с текущим значением следующим образом:
<td>{@html column.html(value)}</td>
Если у вас есть только статический контент, вам, конечно, не нужна функция.
Используйте слоты и ключи для визуализации различных ячеек. Это очень гибкий подход, который используется, например. по DataTable
Компоненты Carbon Svelte.
Столбцы определяют ключ, а ячейки могут быть шаблонизированы с помощью слотов и реквизитов слотов.
Например.
<!-- DataTable.svelte -->
<script>
export let columns;
export let rows;
</script>
<table>
{#each rows as row}
<tr>
{#each columns as column}
{@const value = row[column.key]}
<td>
<slot {value} key = {column.key} />
</td>
{/each}
</tr>
{/each}
</table>
Пример использования:
<script>
import DataTable from './DataTable.svelte';
const rows = [
{ name: 'John', age: 64 },
{ name: 'Jane', age: 46 },
]
const columns = [
{ key: 'name' },
{ key: 'age' },
]
</script>
<DataTable {columns} {rows} let:key let:value>
{#if key == 'name'}
<button>{value}</button>
{:else}
{value} <!-- Fallback to just the cell content -->
{/if}
</DataTable>