Сайт на Nuxt 3 и Vue. Появилась необходимость вставки компонентов в текст статьи с заменой специальных тегов. Например, если в тексте статьи присутствует тег #GALLERY#, то на его место встраивается компонент галереи. Как это можно реализовать?
А сама статья в каком виде хранится? HTML, MD, ещё что-то?
Самый простой способ в любом случае - перегнать в html с vue-компонентами где надо и скомпилировать получившийся код через compile в render функцию.
Aetae, статья в HTML. В данный момент реализовал через разбиение строки функцией "split". Прохожу в "v-for" по получившемуся массиву и строки вывожу в "v-html", а в тех местах, где встречаются специальные вставки подключаю компоненты. Но может быть, есть и более красивое решение.
Aetae, и почему не получится вложенность или поедет вёрстка? Если все теги вложенного компонента правильно закрываются, и теги внешней разметки не теряются при разбиении, разве, должно что-то поехать?
Браузер работает с DOM, v-html - это абстракция над innerHTML, а innerHTML - абстракция над DOM, За одну операцию вставки "текста" он полностью анализирует вставляемое и приводит все теги к окончательному виду, потому что в DOM не может быть незакрытых тегов.
photosho, под простым вариантом я имел ввиду условно такой:
Что позволит использовать в статьях всю мощь html и vue. Только доверие к статьям должно быть соответствующее.:)
Иначе надо будет подключать некий html-парсер на стороне сервера, который вычистит весь мусор(неразрешённые теги и операции) из текста. Ну или можно сделать на фронте при приёме, но это уже костыльно.
Aetae, это вы хорошо сказали, и теперь я убедился, что проблема, действительно, есть. Как раз из-за того, что разметка генерируется в JavaScript и выводится частями. Но как тогда отрендерить всю разметку в строку, чтобы вывести её целиком? В вашем примере получается, что разметка компонента сразу задаётся в виде строки, но этот вариант неудобен для больших компонентов. И не уверен, что он правильный в условиях приложения Nuxt.
Главный вопрос - как встроить их в текст статьи. То есть, тег #GALLERY# из примера в вопросе всё равно будет преобразовываться в некий компонент (<v-gallery/>). Можно хранить в тексте статьи и такое представление. Но вот как заставить Vue подключать их как компоненты...