在这里插入图片描述

📌 模块概述

Markdown编辑器为用户提供了一个简洁而强大的文本编辑方式。Markdown是一种轻量级标记语言,使用简单的语法来表示格式。Markdown编辑器适合那些熟悉Markdown语法的用户,它提供了最高的灵活性和可控性。

Markdown编辑器需要实时预览功能,用户可以在编辑时看到最终的渲染效果。

🔗 完整流程

第一步:初始化编辑器

当用户进入Markdown编辑器时,需要加载笔记的Markdown内容。编辑器应该提供一个分屏视图,左侧是编辑区,右侧是预览区。

第二步:实时渲染

当用户输入Markdown内容时,编辑器需要实时将其渲染为HTML并显示在预览区。这需要使用Markdown解析库来完成。

第三步:保存Markdown内容

保存时,编辑器需要保存原始的Markdown内容,同时生成HTML版本用于显示和搜索。

🔧 Web代码实现

第一步:加载笔记内容

const note = await noteDB.getNote(noteId);

从数据库获取要编辑的笔记。如果是新建笔记,则使用默认的空对象。

第二步:创建分屏编辑器

<div class="markdown-editor">
  <div class="editor-pane">
    <textarea id="markdown-content" placeholder="输入Markdown内容..."></textarea>
  </div>
  <div class="preview-pane">
    <div id="markdown-preview" class="markdown-preview"></div>
  </div>
</div>

创建左右分屏布局。左侧是Markdown编辑区,右侧是实时预览区。

第三步:实时预览Markdown

document.getElementById('markdown-content').addEventListener('input', function() {
  const markdown = this.value;
  const html = marked(markdown);
  document.getElementById('markdown-preview').innerHTML = html;
});

监听编辑区的输入事件,使用marked库将Markdown转换为HTML,实时显示在预览区。

第四步:获取编辑内容

const title = document.getElementById('note-title').value.trim();
const markdownContent = document.getElementById('markdown-content').value;
const htmlContent = marked(markdownContent);

获取标题、Markdown内容和转换后的HTML内容。HTML内容用于显示,Markdown用于编辑。

第五步:验证输入

if (!title) {
  Utils.showToast('笔记标题不能为空', 'error');
  return;
}

验证标题不能为空。如果为空,显示错误提示并中止保存。

第六步:更新现有笔记

const note = await noteDB.getNote(noteId);
note.title = title;
note.content = markdownContent;
note.htmlContent = htmlContent;
note.updatedAt = new Date().toISOString();
await noteDB.updateNote(note);

如果是编辑现有笔记,则更新笔记的标题、Markdown内容和HTML内容。

第七步:创建新笔记

const newNote = {
  id: Date.now(),
  title: title,
  content: markdownContent,
  htmlContent: htmlContent,
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
};
await noteDB.addNote(newNote);

如果是新建笔记,则创建一个新的笔记对象,包含标题、Markdown内容和HTML内容。

第八步:显示保存状态

Utils.showToast('笔记已保存', 'success');

保存成功后显示提示信息,让用户知道笔记已经保存。

🔌 OpenHarmony 原生代码

第一步:导入必要模块

import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';

导入ArkWeb、AbilityKit和CoreFileKit模块。

第二步:定义MarkdownEditorPlugin类

@NativeComponent
export class MarkdownEditorPlugin {
  private context: common.UIAbilityContext;
}

使用@NativeComponent装饰器标记为原生组件。

第三步:初始化JavaScript代理

public init(webviewController: webview.WebviewController): void {
  webviewController.registerJavaScriptProxy(
    new MarkdownEditorJSProxy(this),
    'markdownEditorPlugin',
    ['saveMarkdownNote', 'loadMarkdownNote']
  );
}

注册JavaScript代理,将原生方法暴露给Web端。

第四步:保存Markdown笔记

const notesPath = this.context.cacheDir + '/notes.json';
const fileContent = fileIo.readTextSync(notesPath);
let notes = JSON.parse(fileContent);
const note = notes.find((n: any) => n.id === noteId);

读取笔记文件,查找要保存的笔记。

第五步:更新笔记内容

note.title = title;
note.content = markdownContent;
note.htmlContent = htmlContent;
note.updatedAt = new Date().toISOString();
fileIo.writeTextSync(notesPath, JSON.stringify(notes, null, 2));

更新笔记内容并写回文件。

第六步:加载Markdown笔记

const notesPath = this.context.cacheDir + '/notes.json';
const content = fileIo.readTextSync(notesPath);
const notes = JSON.parse(content);
const note = notes.find((n: any) => n.id === noteId);

从文件系统加载笔记。

第七步:JavaScript代理类

class MarkdownEditorJSProxy {
  private plugin: MarkdownEditorPlugin;
  
  saveMarkdownNote(noteId: number, title: string, markdownContent: string, htmlContent: string): void {
    this.plugin.saveMarkdownNote(noteId, title, markdownContent, htmlContent);
  }
}

代理类作为Web端和原生端的桥梁。

Web-Native 通信

第一步:保存Markdown笔记

cordova.exec(
  function(success) {
    Utils.showToast('笔记已保存', 'success');
  },
  function(error) {
    Utils.showToast('保存失败', 'error');
  },
  'MarkdownEditorPlugin',
  'saveMarkdownNote',
  [noteId, title, markdownContent, htmlContent]
);

调用原生的saveMarkdownNote方法保存笔记。

第二步:加载Markdown笔记

cordova.exec(
  function(note) {
    document.getElementById('markdown-content').value = note.content;
    document.getElementById('markdown-preview').innerHTML = note.htmlContent;
  },
  function(error) {
    console.error('Failed to load note:', error);
  },
  'MarkdownEditorPlugin',
  'loadMarkdownNote',
  [noteId]
);

调用原生的loadMarkdownNote方法加载笔记。

📝 总结

Markdown编辑器功能展示了如何在Cordova与OpenHarmony混合开发中实现一个专业的Markdown编辑工具。通过实时预览和完整的Markdown支持,我们为用户提供了一个强大的编辑环境。

Markdown编辑器的实现涉及到Markdown解析、实时渲染和格式转换等复杂问题,展示了混合开发中处理专业功能的能力。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐