更新记录
1.0.1(2025-04-30) 下载此版本
优化
1.0.0(2025-04-30) 下载此版本
初版发布
平台兼容性
Vue2 | Vue3 |
---|---|
√ | × |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 3.98 app-vue | × | √ | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 | 鸿蒙元服务 |
---|---|---|---|---|
× | × | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
√ | √ | √ | √ | √ | × | √ | √ | √ |
::: hljs-center
zy-markdown-render使用教程
:::
1、介绍
基于uniapp+vue2自定义渲染markdown语法/高亮,适用于h5+小程序+App端。
2、使用教程
2.1渲染markdown
<template>
<view>
<zy-markdown-render :sourceMdContent="markdownString" :showCursor="false"></zy-markdown-render>
</view>
</template>
<script>
export default {
data() {
return {
markdownString: "## 一、标题\n# 一级标题\n## 二级标题\n### 三级标题\n#### 四级标题\n##### 五级标题\n###### 六级标题\n\n## 二、粗体、斜体、下划线、删除线\n**粗体**\n\n*斜体*\n\n***斜体加粗***\n\n~~删除线~~\n\n++下划线++\n\n## 三、表格\n|表头|表头|表头|\n|-|-|-|\n|内容|内容|内容|\n|内容|内容|内容|\n|内容|内容|内容|\n|内容|内容|内容|\n\n## 四、代码块\n```javaScript\nconsole.log('哈哈,你真好!');\nconsole.log('哈哈,有你真好!');\n```\n\n## 五、段落引用\n> 我引用了......\n\n## 六、链接\n[百度,点我跳转](www.baidu.com)\n\n## 七、图片\n\n\n"
};
},
methods: {
}
};
</script>
2.2模拟流式输出
<template>
<view>
<button @tap="typeWriter()">流式输出</button>
<zy-markdown-render :sourceMdContent="output" :showCursor="false"></zy-markdown-render>
</view>
</template>
<script>
export default {
data() {
return {
scrollIntoView: '',
output: '',
index: 0,
markdownString: "## 一、标题\n# 一级标题\n## 二级标题\n### 三级标题\n#### 四级标题\n##### 五级标题\n###### 六级标题\n\n## 二、粗体、斜体、下划线、删除线\n**粗体**\n\n*斜体*\n\n***斜体加粗***\n\n~~删除线~~\n\n++下划线++\n\n## 三、表格\n|表头|表头|表头|\n|-|-|-|\n|内容|内容|内容|\n|内容|内容|内容|\n|内容|内容|内容|\n|内容|内容|内容|\n\n## 四、代码块\n```javaScript\nconsole.log('哈哈,你真好!');\nconsole.log('哈哈,有你真好!');\n```\n\n## 五、段落引用\n> 我引用了......\n\n## 六、链接\n[百度,点我跳转](www.baidu.com)\n\n## 七、图片\n\n\n"
};
},
methods: {
typeWriter() {
if (this.index >= this.markdownString.length) return;
let currentOutput = '';
let specialStart = false;
// 检查是否遇到 Markdown 语法字符
if (this.markdownString.startsWith('```', this.index)) {
// 处理代码块
const end = this.markdownString.indexOf('```', this.index + 3);
if (end !== -1) {
let codeBlock = this.markdownString.slice(this.index, end + 3);
let lines = codeBlock.split('\n');
let startLine = lines.shift();
let endLine = lines.pop();
currentOutput = startLine + '\n';
this.index += startLine.length + 1;
this.output += currentOutput;
let outputCodeLines = () => {
if (lines.length > 0) {
let line = lines.shift();
this.output += line + '\n';
this.index += line.length + 1;
setTimeout(outputCodeLines, 200);
} else {
this.output += endLine;
this.index += endLine.length;
setTimeout(this.typeWriter.bind(this), 200);
}
};
outputCodeLines();
return;
}
} else if (this.markdownString.startsWith('|', this.index)) {
// 处理表格
let tableEnd = this.markdownString.indexOf('\n\n', this.index);
if (tableEnd === -1) tableEnd = this.markdownString.length;
let tableContent = this.markdownString.slice(this.index, tableEnd);
let lines = tableContent.split('\n');
// 定义逐行输出函数
let outputTableLines = () => {
if (lines.length > 0) {
let line = lines.shift();
this.output += line + '\n';
this.index += line.length + 1;
// 如果是表头或分隔符,稍微延长显示时间
let delay = line.includes('|---') ? 300 : 150; // 调整延迟时间
setTimeout(outputTableLines, delay);
} else {
setTimeout(this.typeWriter.bind(this), 200);
}
};
outputTableLines();
return;
} else if (/^#+/.test(this.markdownString.slice(this.index))) {
// 处理标题
let headerMatch = this.markdownString.slice(this.index).match(/^#+\s*/);
if (headerMatch) {
currentOutput = headerMatch[0];
this.index += currentOutput.length;
let contentEnd = this.markdownString.indexOf('\n', this.index);
if (contentEnd === -1) contentEnd = this.markdownString.length;
let titleContent = this.markdownString.slice(this.index, contentEnd);
while (titleContent.length > 0 && currentOutput.length < 5) {
currentOutput += titleContent.charAt(0);
titleContent = titleContent.slice(1);
}
this.index += currentOutput.length - headerMatch[0].length;
specialStart = true;
}
} else if (this.markdownString.startsWith('^', this.index)) {
// 处理上标
const match = this.markdownString.slice(this.index).match(/^\^(.*?)\^/);
if (match) {
currentOutput = `<sup>${match[1]}</sup>`;
this.index += match[0].length;
specialStart = true;
}
} else if (this.markdownString.startsWith('~', this.index)) {
// 处理下标
const match = this.markdownString.slice(this.index).match(/^~(.*?)~/);
if (match) {
currentOutput = `<sub>${match[1]}</sub>`;
this.index += match[0].length;
specialStart = true;
}
} else if (this.markdownString.startsWith('++', this.index)) {
// 处理下划线
const match = this.markdownString.slice(this.index).match(/^\+\+(.*?)\+\+/);
if (match) {
currentOutput = `<u>${match[1]}</u>`;
this.index += match[0].length;
specialStart = true;
}
} else if (this.markdownString.startsWith(':::', this.index)) {
// 处理居左、居中、居右
const match = this.markdownString.slice(this.index).match(
/^:::\s*(hljs-left|hljs-center|hljs-right)\s*\n([\s\S]*?)\n:::/);
if (match) {
const alignClass = match[1]; // 获取对齐方式
const content = match[2]; // 获取内容
const lines = content.split('\n');
// 输出起始标签
currentOutput = `<div class="${alignClass}">\n`;
this.index += match[0].length - content.length - 4; // 跳过起始标记
this.output += currentOutput;
// 定义逐行输出函数
let outputAlignLines = () => {
if (lines.length > 0) {
let line = lines.shift();
this.output += line + '\n';
this.index += line.length + 1;
setTimeout(outputAlignLines, 200);
} else {
// 输出结束标签
this.output += '</div>';
this.index += 4; // 跳过结束标记
setTimeout(this.typeWriter.bind(this), 200);
}
};
outputAlignLines();
return;
}
}
// 如果没有遇到特殊字符,则确保输出至少 5 个字符
while (this.index < this.markdownString.length && (currentOutput.length < 5 || specialStart)) {
let currentChar = this.markdownString.charAt(this.index);
currentOutput += currentChar;
this.index++;
// 如果遇到新的 Markdown 语法字符,停止当前段落
if (
this.markdownString.startsWith('```', this.index) ||
this.markdownString.startsWith('|', this.index) ||
/^#+/.test(this.markdownString.slice(this.index)) ||
this.markdownString.startsWith('^', this.index) ||
this.markdownString.startsWith('~', this.index) ||
this.markdownString.startsWith('++', this.index) ||
this.markdownString.startsWith(':::', this.index)
) {
break;
}
}
// 更新输出内容
this.output += currentOutput;
// 继续下一次输出
setTimeout(this.typeWriter.bind(this), 200); // 调整时间间隔以控制输出速度
},
}
};
</script>