Nuxt / Vue JS - 为降价文件编写 HTML 模板

Nuxt / Vue JS - Writing a HTML template for a markdown file

我有一个包含发行说明的 Markdown 文件。例如:

## 1.0.0

### New
#### Added new language support

### Fixed
#### This is fixed
#### This is fixed

### Changed
#### Something changed

### Feature
#### New Feature Added

## 2.0.0

### New
#### Added new language support

在我的 HTML 中,我想遍历所有新版本的发行说明。我在页面中查询了文档,如下所示:

<template>
    <changelog :article="article"/> 
</template>

<script lang="ts">
  import Vue from "vue";
  export default Vue.extend({
    async asyncData({ $content }) {
      const article = await $content("changelogs/iOS/changelog").fetch();
      return { article };
    },  
    watchQuery: true,
  });
</script>

在我的组件中,我有:

<template>
    <article :document="article">
</template>

我希望结果是这样的:

内容的解析结果存储在article.body.children[]中。每个child包含以下节点数据:

  • tag - HTML 标签(例如,h2h3
  • type - 元素类型(例如,elementtext
  • value - 元素值(文本内容)
  • props - 额外的道具数据,包括 id
  • children[] - Child 个节点

您可以使用该信息将节点解析为存储发布信息的便捷数据结构,例如:

  • title 来自 text child 的 h2
  • id 来自 propsh2
  • changes[] 保存更改行,每行包含:
    • id 来自 propsh4
    • type 来自 text child 的 h3
    • text 来自 text child 的 h4
const elems = article.body.children.filter(node => node.type === 'element')
let rel = {}
let type = ''
for (const node of elems) {
  if (node.tag === 'h2') {
    rel = {
      id: node.props.id,
      title: node.children.find(c => c.type === 'text').value,
      changes: []
    }
    this.releases.push(rel)

  } else if (node.tag === 'h3') {
    type = node.children.find(c => c.type === 'text').value

  } else if (node.tag === 'h4') {
    rel.changes.push({
      id: node.props.id,
      type,
      text: node.children.find(c => c.type === 'text').value,
    })
  }
}

然后,使用v-for渲染上面解析的发布信息列表。

<article v-for="rel of releases" :key="rel.id">
  <h3 class="title">{{ rel.title }}</h3>
  <section class="change" v-for="change in rel.changes" :key="change.id">
    <div class="type" :class="change.type">{{ change.type }}</div>
    <div class="text">{{ change.text }}</div>
  </section>
</article>

demo