Skip to content

Markdown 文本解析 4.4.0

该组件基于 marked(库大小40KB) 实现,支持将 Markdown 文本解析为富文本内容。

平台差异说明

|App(vue)|App(uvue/uni-app-x)|App(nvue)|H5|小程序| |:-😐:-😐:-😐:-😐:-😐:-😐 |√|x|√|√|

基础用法

通过 content 属性传入 Markdown 文本内容。

vue
<template>
  <view class="u-page">
    <view class="u-page__item">
      <up-markdown :content="basicContent"></up-markdown>
    </view>
  </view>
</template>
js
<script setup>
import { ref } from 'vue';

const basicContent = ref(`# 标题1
这是段落文本,包含**粗体**和*斜体*文本。

## 标题2
这是一个链接:[uview-plus](https://ijry.github.io/uview-plus)

### 列表示例
- 列表项1
- 列表项2
- 列表项3

> 这是一个引用块

---

段落中的行内代码: \`console.log('Hello World')\``);
</script>

显示代码块行号

通过 show-line-number 属性控制是否显示代码块行号。

vue
<template>
  <view class="u-page">
    <view class="u-page__item">
      <up-markdown :content="codeContent" :show-line-number="true"></up-markdown>
    </view>
  </view>
</template>
js
<script setup>
import { ref } from 'vue';

const codeContent = ref(`# 代码示例

以下是一个JavaScript函数:

\`\`\`javascript
function hello(name) {
    console.log('Hello, ' + name + '!');
}

hello('World');
\`\`\`

以下是一个Python示例:

\`\`\`python
def hello(name):
    print(f"Hello, {name}!")

hello("World")
\`\`\``);
</script>

深色主题

通过 [theme](file:///Users/jry/Documents/www/Ai/dify/web/tailwind.config.js#L9-L115) 属性设置主题样式,可选值为 light(默认)和 [dark](file:///Users/jry/Documents/www/Ai/dify/web/types/app.ts#L12-L12)。

vue
<template>
  <view class="u-page">
    <view class="u-page__item">
      <up-markdown :content="basicContent" theme="dark"></up-markdown>
    </view>
  </view>
</template>
js
<script setup>
import { ref } from 'vue';

const basicContent = ref(`# 标题1
这是段落文本,包含**粗体**和*斜体*文本。

## 标题2
这是一个链接:[uview-plus](https://ijry.github.io/uview-plus)

### 列表示例
- 列表项1
- 列表项2
- 列表项3

> 这是一个引用块

---

段落中的行内代码: \`console.log('Hello World')\``);
</script>

AI流式内容显示

模拟AI逐步输出文字的效果。

vue
<template>
  <view class="u-page">
    <view class="u-page__item">
      <up-markdown :content="streamingContent" :show-line-number="true"></up-markdown>
      <view style="flex-direction: row; margin-top: 10px;">
        <up-button 
          type="primary" 
          size="mini" 
          :text="isStreaming ? '停止' : '开始'" 
          @click="toggleStreaming"
          style="margin-right: 10px;"
        ></up-button>
        <up-button 
          type="default" 
          size="mini" 
          text="重置" 
          @click="resetStreaming"
        ></up-button>
      </view>
    </view>
  </view>
</template>
js
<script setup>
import { ref, onBeforeUnmount } from 'vue';

const fullAIContent = ref(`# AI助手回答

你好!我是AI助手,正在为你逐步生成回答内容...

## 问题分析

让我来分析你提出的问题:

1. 需要实现流式内容显示
2. 模拟AI逐步输出文字的效果
3. 使用定时器控制内容显示速度

## 解决方案

我们可以使用以下方法实现:

### 第一步:创建数据模型
\`\`\`javascript
data() {
  return {
    streamingContent: '',
    isStreaming: false,
    streamTimer: null
  }
}
\`\`\`

### 第二步:实现流式显示逻辑
\`\`\`javascript
methods: {
  startStreaming() {
    // 实现流式显示逻辑
  }
}
\`\`\`

## 总结

以上就是实现流式内容显示的基本方法。通过定时器控制内容逐字显示,可以营造出AI正在思考和逐步输出的效果。

这种交互方式在现代Web应用中非常常见,特别是在AI助手类产品中。

---

*内容生成完毕*`);

const streamingContent = ref('');
const isStreaming = ref(false);
const streamTimer = ref(null);
const streamIndex = ref(0);

// 开始/停止流式显示
const toggleStreaming = () => {
  if (isStreaming.value) {
    stopStreaming();
  } else {
    startStreaming();
  }
};

// 开始流式显示
const startStreaming = () => {
  if (isStreaming.value) return;
  
  // 如果是重新开始,重置索引
  if (streamIndex.value >= fullAIContent.value.length) {
    streamIndex.value = 0;
    streamingContent.value = '';
  }
  
  isStreaming.value = true;
  streamTimer.value = setInterval(() => {
    if (streamIndex.value < fullAIContent.value.length) {
      streamingContent.value += fullAIContent.value[streamIndex.value];
      streamIndex.value++;
    } else {
      stopStreaming();
    }
  }, 50); // 50ms间隔,模拟AI逐步输出
};

// 停止流式显示
const stopStreaming = () => {
  if (streamTimer.value) {
    clearInterval(streamTimer.value);
    streamTimer.value = null;
  }
  isStreaming.value = false;
};

// 重置流式显示
const resetStreaming = () => {
  stopStreaming();
  streamingContent.value = '';
  streamIndex.value = 0;
};

// 组件销毁前清理定时器
onBeforeUnmount(() => {
  stopStreaming();
});
</script>

Props

参数名说明类型默认值可选值
contentmarkdown内容String--
previewImg是否启用图片预览Booleantruetrue / false
showLineNumber是否显示代码块行号Booleanfalsetrue / false
theme主题样式Stringlightlight / dark

Event

事件名说明回调参数
---