简体   繁体   English

将组件反应到 SvelteKit - 属性(JSX 渲染)中具有 HTML 的对象到脚本标记

[英]React Components to SvelteKit - Objects with HTML in attribute (JSX rendering) to Script tag

Since I'm changing a React project to SvelteKit, I've got a specific situation that made me a lot curious about it.由于我正在将一个 React 项目更改为 SvelteKit,我遇到了一个让我很好奇的特殊情况。

Let's suppose that I do have a component in React that receives the object columnsMockExample as props, for example, and consumes an HTML inside of the object, as:假设我在 React 中确实有一个组件接收 object columnsMockExample作为道具,例如,并在 object 中使用 HTML,如下所示:

const columnsMockExample = [{name: 'Column 1', html: '<div>Inner HTML example</div>' }]
<ColumnsComponent columnsProp={columnsMockExample}/>

So, in React, we could map this object to consume it and show every .html inside of columnsMockExample :因此,在 React 中,我们可以使用 map 这个 object 来使用它并显示.html中的每个columnsMockExample

{props.columnsProp.map((columnFromMockExample) => columnFromMockExample.html)};

So then, here is the question: as SvelteKit has the <script/> tag apart from the HTML, how can I create my object columnsMockExample inside of the SvelteKit <script/> tag since it is not JSX?那么问题来了:由于 SvelteKit 除了 HTML 之外还有<script/>标签,我如何在 SvelteKit <script/>标签内创建我的 object columnsMockExample因为它不是 JSX?

wrong SvelteKit script example is written below:错误的 SvelteKit 脚本示例如下:

<script> 
  const columnsMockExample = [{name: 'Column 1', html: '<div>Inner HTML example</div>' }] 
</script>

Thank you.谢谢你。

If it's pure HTML (no Svelte-specific code, just raw HTML), you can use the @html directive:如果它是纯 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}

Docs: https://svelte.dev/docs#template-syntax-html文档: https://svelte.dev/docs#template-syntax-html

If there's Svelte components or click handlers etc in there, that doesn't work though.如果那里有 Svelte 组件或点击处理程序等,那是行不通的。 In that case you need to rewrite the code using components and slots ( https://svelte.dev/docs#template-syntax-slot ) and/or the svelte:component tag ( https://svelte.dev/docs#template-syntax-svelte-component ) - how exactly depends on what your goal is.在这种情况下,您需要使用组件和插槽 ( https://svelte.dev/docs#template-syntax-slot ) 和/或svelte:component标签 ( https: //svelte.dev/docs#template) 重写代码-syntax-svelte-component ) - 究竟如何取决于你的目标是什么。

There are several different approaches that can be taken here, all of which are a bit different.这里可以采用几种不同的方法,所有方法都有点不同。

  1. Use slots to make each column render a cell and render entire rows via the parent components slot.使用插槽使每列呈现一个单元格并通过父组件插槽呈现整行。 Example can be seen in this question .可以在这个问题中看到示例。

  2. Define separate components and instead of passing HTML, you pass the component class. As of now this is a bit of a pain, because components cannot be defined in the same file.定义单独的组件,而不是传递 HTML,而是传递组件 class。到目前为止,这有点麻烦,因为不能在同一个文件中定义组件。 REPL example 示例

    The key is to render the components dynamically via <svelte:component /> and pass in the current column value as a well-known prop that is the same for all cell components.关键是通过<svelte:component />动态呈现组件,并将当前列值作为众所周知的 prop 传递,该 prop 对于所有单元格组件都是相同的。

  3. Instead of using components actually render HTML directly using {@html} .而不是使用组件实际渲染 HTML 直接使用{@html} I do absolutely not recommend this, because it makes it easy to create XSS vulnerabilities.绝对不推荐这样做,因为它很容易创建 XSS 漏洞。 REPL example 示例

    The key here is to provide the content as a function of the column value, like this:这里的关键是将内容提供为列值的 function,如下所示:

     const columns = [ { key: 'name', html: value => `<button>${value}</button>` }, { key: 'age', html: value => `<em>${value}</em>` }, ]

    So this can be rendered with the current value like this:所以这可以用这样的当前值来呈现:

     <td>{@html column.html(value)}</td>

    If you only have static content, you do not need a function of course.如果你只有 static 内容,你当然不需要 function。

  4. Use slots and keys to render the different cells.使用插槽和键来渲染不同的单元格。 This is a very flexible approach which is used eg by the DataTable of the Carbon Svelte components .这是一种非常灵活的方法,例如由Carbon Svelte 组件DataTable使用。

    The columns define the key, and the cells can be templated via slots and slot props.列定义键,单元格可以通过插槽和插槽道具进行模板化。

    Eg例如

    <.-- 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>

    Usage example:使用示例:

     <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>

    REPL REPL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM