更新记录

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![豆包](https://lf-flow-web-cdn.doubao.com/obj/flow-doubao/samantha/logo-icon-white-bg.png)\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![豆包](https://lf-flow-web-cdn.doubao.com/obj/flow-doubao/samantha/logo-icon-white-bg.png)\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>

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问