从Sanity拉取post.body返回Block结构而非纯文本,如何解决?
解决Sanity拉取Block结构而非纯文本的问题
原因说明
你的Sanity中body字段是富文本(Block Content)类型,GROQ查询默认会返回该字段的完整Block结构(包含文本、样式、标记等元数据),这是Sanity存储富文本的标准行为,并非异常。
解决方案
方案一:直接提取纯文本(仅需文本时使用)
修改GROQ查询,通过语法直接从Block结构中提取文本内容,甚至拼接成完整字符串:
提取所有文本片段(数组形式)
const query = groq`*[ _type == "post" ]{ title, slug, mainImage, body: body[]->children[].text } | order(_publishedAt desc)`;
此时post.body是文本片段数组,可通过{{ post.body.join(' ') }}拼接成字符串显示。
直接拼接为完整字符串
const query = groq`*[ _type == "post" ]{ title, slug, mainImage, body: join(body[]->children[].text, " ") } | order(_publishedAt desc)`;
这种方式返回的post.body就是纯文本字符串,直接用<p>{{ post.body }}</p>即可正常显示。
方案二:正确渲染富文本(推荐,保留格式)
如果需要保留富文本的格式(如换行、加粗、链接等),不要手动解析Block结构,使用Vue适配的Sanity富文本渲染组件:
- 安装依赖:
npm install sanity-blocks-vue-component
- 在组件中使用:
<template> <Header /> <h1>This is the blog page!</h1> <div v-for="post in posts" :key="post._id" class="post"> <div class="post-img"> <img :src="$urlFor(post.mainImage).url()" :alt="`${post.title}`" /> </div> <div class="post-text"> <div class="post-text__title"> <a :href="`${post.slug.current}`" ><h2>{{ post.title }}</h2></a > </div> <div class="post-text__description"> <SanityBlocks :blocks="post.body" /> </div> </div> </div> </template> <script setup> import SanityBlocks from 'sanity-blocks-vue-component'; const query = groq`*[ _type == "post" ]{title, slug, mainImage, body} | order(_publishedAt desc)`; const { data: posts } = await useSanityQuery(query); </script>
该组件会自动将Block结构转换为对应的HTML元素,完整保留编辑时的富文本格式。
内容的提问来源于stack exchange,提问作者Joshua Schmidt
相关产品推荐
相关产品推荐

