Выбрасывайте по-настоящему «сырой» html в Свелте - PullRequest
2 голосов
/ 25 февраля 2020

Я получаю необработанные html фрагменты из безголовой CMS, которые мне нужно отобразить как есть в приложении Sapper.

Это также включает случаи, когда я получаю открывающий тег и соответствующий закрывающий тег как две части HTML, между которыми я добавляю компонент Svelte.

<script>
    import MyComponent from './MyComponent.svelte'

    // example snippets coming from headless CMS
    const prefix = '<p class="test">' 
    const suffix = '</p>'
</script>

<!-- use snippets as-is -->
{@html prefix}
<MyComponent />
{@html suffix}

См. https://svelte.dev/repl/4c1bf80ae00e476587344b6065e7346e?version=3.19.1

Однако Svelte ожидает, что каждый элемент, отображаемый с @ html, является автономным элементом и пытается «исправить» распространенные ошибки. Например, он добавит закрывающий тег к фрагменту префикса, перемещая <MyComponent/> -часть из p.

Есть ли способ вообще обойти это поведение? Или, более конкретно - возможно ли окружить визуализированные компоненты произвольным необработанным HTML?

как побочным узлом: он работает как более саперное приложение, и отрендеренная версия страницы на стороне сервера правильно испускает необработанный HTML. Когда рендеринг на стороне клиента срабатывает, поведение меняется.

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Вот злой путь ...

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ Перемещение управляемых элементов Svelte под ноги не может быть хорошей идеей, и я совершенно не понимаю, какие неблагоприятные побочные эффекты вы могли бы встречайте дальше!

Я особенно рекомендую не использовать это в {#each} блоках, особенно в ключевых, так как Svelte захочет изменить порядок своих элементов и может расстроиться, если они не там, где их ожидают в DOM .

... но, может быть, это поможет вам разобраться в простых случаях. Вы будете судьей.

Моя идея состоит в том, чтобы отобразить полную сцепленную строку (префикс + суффикс) с дополнительным элементом, который я могу взять и заменить на компонент, уже отрисованный независимо Svelte, вне этого фрагмента.

Вот трюк:

{@html prefix + '<span id="vslot"></span>' + suffix}

Вот пример компонента, который реализует трюк:

<script>
    import { afterUpdate } from 'svelte'

    export let prefix
    export let suffix

    let wrap
    let content

    afterUpdate(() => {
        const vslot = wrap.querySelector('#vslot')
        vslot.parentNode.replaceChild(content, vslot)
    })
</script>

<div bind:this={wrap}>
    {@html prefix + '<span id="vslot"></span>' + suffix}
</div>

<div bind:this={content}>
    <slot />
</div>

Вы бы использовали его так:

<Wrapper {prefix} {suffix}>
    <MyComponent />
</Wrapper>

РЕПЛ

0 голосов
/ 25 февраля 2020

Вы можете использовать слоты для достижения аналогичного результата, оборачивая компонент внутри другого компонента. Вот официальная документация: https://svelte.dev/tutorial/slots

...