"{"时间":1679496880268,"块":[{"id":"82C13q17QU","类型":"段落","数据":{"文本":"标题"}},{" id":"aQ7sSPshJO","type":"段落","data":{"text":"描述"}},{"id":"P0cESzO_a-","type":"image","data ":{"文件":{"url":"/uploads/render_3fc01e6769.png","mime":"image/png","高度":1000,"宽度":1000,"尺寸":672.3," alt":"render.png","格式":{"thumbnail":{"name":"thumbnail_render.png","hash":"thumbnail_render_3fc01e6769","ext":".png","mime": "image/png","path":null,"width":156,"height":156,"size":49.79,"url":"/uploads/thumbnail_render_3fc01e6769.png"},"small":{"名称":"small_render.png","哈希":"small_render_3fc01e6769","ext":".png","mime":"image/png","路径":null,"宽度":500,"高度":500,"大小":529.93,"url":"/uploads/small_render_3fc01e6769.png"},"medium":{"name":"medium_render.png","hash":"medium_render_3fc01e6769","ext" :“.png”,“mime”:“image/png”,“路径”:null,“宽度”:750,“高度”:750,“大小”:1200.69,“url”:“/uploads/medium_render_3fc01e6769。 png"}}},"caption":"一杯咖啡","withBorder":false,"拉伸":false,"withBackground":false}}],"version":"2.23.2"}"
我想在Nuxt 3中显示为html。希望有人可以帮助我! 谢谢!
我通过在 Nuxt3 TS 项目中创建
RichTextBlocks.vue
组件解决了这个问题。它使用Tailwind 的排版插件。这是我的组件:
<script lang="ts" setup>
import type { RichTextBlockChild, RichTextBlocks } from '@/ts/interfaces/strapi-models/strapiRichText'
import { RichTextBlockChildType, RichTextBlockFormat, RichTextBlockType } from '@/ts/interfaces/strapi-models/strapiRichText'
defineProps<{
data?: RichTextBlocks[]
}>()
function renderList(block: RichTextBlocks) {
let html = ''
block.children.forEach((child) => {
html += '<li>'
child.children.forEach((childChild) => {
if (childChild.type === RichTextBlockChildType.text) {
if (childChild.bold)
html += `<strong>${childChild.text}</strong>`
else if (childChild.italic)
html += `<i>${childChild.text}</i>`
else if (childChild.underline)
html += `<u>${childChild.text}</u>`
else if (childChild.strikethrough)
html += `<s>${childChild.text}</s>`
else
html += childChild.text
}
})
html += '</li>'
})
return html
}
function renderText(children: RichTextBlockChild[]) {
let html = ''
children.forEach((childChild) => {
if (childChild.type === RichTextBlockChildType.text) {
if (childChild.bold)
html += `<strong>${childChild.text}</strong>`
else if (childChild.italic)
html += `<i>${childChild.text}</i>`
else if (childChild.underline)
html += `<u>${childChild.text}</u>`
else if (childChild.strikethrough)
html += `<s>${childChild.text}</s>`
else
html += childChild.text
}
})
return html
}
</script>
<template>
<div class="prose prose-slate prose-a:text-blue-600">
<template v-for="(block, index) in data" :key="index">
<!-- Paragraph -->
<p v-if="block && block.type === RichTextBlockType.paragraph">
<template v-for="(child, childIndex) in block.children" :key="`${childIndex}-${index}`">
<strong v-if="child.type === RichTextBlockChildType.text && child.bold">{{ child.text }}</strong>
<i v-else-if="child.type === RichTextBlockChildType.text && child.italic">{{ child.text }}</i>
<u v-else-if="child.type === RichTextBlockChildType.text && child.underline">{{ child.text }}</u>
<s v-else-if="child.type === RichTextBlockChildType.text && child.strikethrough">{{ child.text }}</s>
<code v-else-if="child.type === RichTextBlockChildType.text && child.code">{{ child.text }}</code>
<a v-else-if="child.type === RichTextBlockChildType.link && child.url" :href="child.url" v-html="renderText(child.children)" />
<template v-else-if="child.type === RichTextBlockChildType.text">
{{ child.text }}
</template>
</template>
</p>
<!-- Lists -->
<ul v-if="block && block.type === RichTextBlockType.list && block.format === RichTextBlockFormat.unordered" v-html="renderList(block)" />
<ol v-if="block && block.type === RichTextBlockType.list && block.format === RichTextBlockFormat.ordered" v-html="renderList(block)" />
<!-- Headings -->
<h1 v-if="block && block.type === RichTextBlockType.heading && block.level === 1" v-html="renderText(block.children)" />
<h2 v-if="block && block.type === RichTextBlockType.heading && block.level === 2" v-html="renderText(block.children)" />
<h3 v-if="block && block.type === RichTextBlockType.heading && block.level === 3" v-html="renderText(block.children)" />
<h4 v-if="block && block.type === RichTextBlockType.heading && block.level === 4" v-html="renderText(block.children)" />
<h5 v-if="block && block.type === RichTextBlockType.heading && block.level === 5" v-html="renderText(block.children)" />
<h6 v-if="block && block.type === RichTextBlockType.heading && block.level === 6" v-html="renderText(block.children)" />
<!-- Image -->
<nuxt-img
v-if="block && block.type === RichTextBlockType.image && block.image"
provider="imagekit"
:src="getPathForImage(block.image)"
width="1000"
:placeholder="15"
:modifiers="{ f: 'webp' }"
lazy="true"
:alt="block.image.alternativeText ?? ''"
:title="block.image.name"
class=""
/>
</template>
</div>
</template>
它支持 TS,这是我的
strapiRichText.ts
文件,其中包含接口:
import type StrapiImage from "./image";
export enum RichTextBlockType {
paragraph = 'paragraph',
list = 'list',
heading = 'heading',
image = 'image',
}
export enum RichTextBlockFormat {
unordered = 'unordered',
ordered = 'ordered',
}
export enum RichTextBlockChildType {
text = 'text',
list_item = 'list-item',
link = 'link',
}
export interface RichTextBlocks {
type: RichTextBlockType;
children: RichTextBlockChild[];
format?: RichTextBlockFormat
level?: number
image?: StrapiImage
}
export interface RichTextBlockChild {
text: string
url: string
type: RichTextBlockChildType
children: RichTextBlockChild[]
bold?: boolean;
underline?: boolean;
italic?: boolean;
strikethrough?: boolean;
code?: boolean;
}
在我的其他组件或页面中,我可以像这样使用我的组件:
<RichTextBlocks v-if="props.data?.text" :data="props.data?.text" class="mb-10" />
我希望这对将来的任何人都有帮助!
应该有一种方法可以将富文本查询为markdown,参见:https://strapi.io/blog/build-a-blog-with-next-react-js-strapi
然后您应该能够使用
vue-markdown
将富文本内容呈现为格式化 HTML:
<vue-markdown>{{ markdownResponse }}</vue-markdown>