feat(mini-program): 剧本卡片支持 Markdown 渲染

实现内容:
- 扩展 Markdown 组件支持三级标题 (###) 和粗体 (**text**)
- ScriptView.vue 卡片摘要使用 Markdown 组件渲染
- 新增 ScriptDetailView.vue 剧本详情页,展示完整 Markdown 内容
- 点击卡片可跳转查看详情,"路径映射"按钮使用@click.stop 避免事件冒泡

修改文件:
- components/Markdown.vue: 添加 h3 标题、粗体解析和样式
- pages/main/ScriptView.vue: 导入 Markdown 组件,修改摘要渲染方式,添加跳转逻辑
- pages/main/ScriptDetailView.vue: 新建详情页,展示剧本完整内容
- pages.json: 注册 ScriptDetailView 页面

解决 issues: 小程序"创造未来"页面剧本内容以纯文本显示,
            无法正确渲染 Markdown 格式(标题、列表、粗体等)
This commit is contained in:
2026-04-07 21:28:44 +08:00
parent 42d7bb3cb5
commit 86b3fa8f84
4 changed files with 486 additions and 80 deletions
+63 -5
View File
@@ -4,7 +4,10 @@
<!-- 分割线 -->
<view v-if="block.type === 'hr'" class="markdown-hr"></view>
<!-- 标题 -->
<!-- 三级标题 -->
<text v-else-if="block.type === 'h3'" class="markdown-h3">{{ block.content }}</text>
<!-- 四级标题 -->
<text v-else-if="block.type === 'h4'" class="markdown-h4">{{ block.content }}</text>
<!-- 列表项 -->
@@ -13,8 +16,10 @@
<text class="li-content">{{ block.content }}</text>
</view>
<!-- 普通段落 -->
<text v-else class="markdown-p">{{ block.content }}</text>
<!-- 普通段落处理粗体 -->
<text v-else class="markdown-p">
<text v-for="(segment, segIndex) in block.segments" :key="segIndex" :class="segment.bold ? 'bold' : ''">{{ segment.text }}</text>
</text>
</view>
</view>
</template>
@@ -48,6 +53,13 @@ const parsedBlocks = computed(() => {
continue
}
// 三级标题 ###
const h3Match = trimmed.match(/^###\s+(.+)/)
if (h3Match) {
blocks.push({ type: 'h3', content: h3Match[1] })
continue
}
// 四级标题 ####
const h4Match = trimmed.match(/^####\s+(.+)/)
if (h4Match) {
@@ -62,12 +74,43 @@ const parsedBlocks = computed(() => {
continue
}
// 普通段落
blocks.push({ type: 'p', content: trimmed })
// 普通段落(处理粗体 **text**
const segments = parseBoldText(trimmed)
blocks.push({ type: 'p', content: trimmed, segments })
}
return blocks
})
// 解析粗体文本 **text**
const parseBoldText = (text) => {
const segments = []
const boldRegex = /\*\*(.+?)\*\*/g
let lastIndex = 0
let match
while ((match = boldRegex.exec(text)) !== null) {
// 添加粗体前的普通文本
if (match.index > lastIndex) {
segments.push({ text: text.slice(lastIndex, match.index), bold: false })
}
// 添加粗体文本(去掉 ** 标记)
segments.push({ text: match[1], bold: true })
lastIndex = match.index + match[0].length
}
// 添加剩余的普通文本
if (lastIndex < text.length) {
segments.push({ text: text.slice(lastIndex), bold: false })
}
// 如果没有粗体,返回单个段落
if (segments.length === 0) {
segments.push({ text, bold: false })
}
return segments
}
</script>
<style scoped>
@@ -90,6 +133,15 @@ const parsedBlocks = computed(() => {
}
/* 标题 */
.markdown-h3 {
display: block;
font-size: 30rpx;
font-weight: 600;
color: rgba(243, 232, 255, 0.95);
margin: 20rpx 0 12rpx 0;
line-height: 1.4;
}
.markdown-h4 {
display: block;
font-size: 28rpx;
@@ -131,4 +183,10 @@ const parsedBlocks = computed(() => {
line-height: 1.6;
word-break: break-all;
}
/* 粗体文本 */
.bold {
font-weight: 600;
color: rgba(243, 232, 255, 0.9);
}
</style>