0
0
Lập trình
NM

Xây Dựng Trình Soạn Thảo Văn Bản Đầy Đủ Tính Năng Trong React

Đăng vào 4 tháng trước

• 6 phút đọc

Chủ đề:

KungFuTech

Giới Thiệu

Trong bài viết này, tôi sẽ chia sẻ cách tiếp cận từng bước để xây dựng một trình soạn thảo văn bản đầy đủ tính năng trong React bằng cách sử dụng Lexical kết hợp với LexKit. Việc xây dựng một trình soạn thảo văn bản không chỉ đơn thuần là hiển thị và chỉnh sửa văn bản, mà còn phải tích hợp nhiều tính năng phong phú để nâng cao trải nghiệm người dùng.

Tại Sao Chọn Lexical?

Lý do tôi chọn Lexical thay vì các lựa chọn khác như Tiptap rất đơn giản: tốc độ ⚡. Lexical mang lại hiệu suất cao và khả năng mở rộng tốt, nhưng việc làm việc với Lexical có thể hơi khó khăn do nó có cấu trúc thấp và đòi hỏi nhiều mã khởi tạo. Đó là lý do tại sao tôi đã phát triển LexKit - một lớp mã nguồn mở trên Lexical giúp giảm thiểu sự phức tạp và cải thiện trải nghiệm phát triển.

LexKit Là Gì?

LexKit mang đến:

  • Tính an toàn kiểu: giúp phát hiện lỗi trong quá trình biên dịch.
  • Các mẫu sử dụng sẵn: dễ dàng tích hợp vào ứng dụng của bạn.
  • Khả năng mở rộng: bạn có thể dễ dàng thêm các tiện ích mở rộng mà không cần phải viết lại mã.

👉 Tài liệu chi tiết có tại lexkit.dev/docs

Cài Đặt LexKit

Để bắt đầu, trước tiên bạn cần cài đặt LexKit và Lexical vào dự án của mình:

bash Copy
npm install @lexkit/editor

Tiếp theo, cài đặt các gói Lexical cần thiết:

bash Copy
npm install lexical @lexical/react @lexical/html @lexical/markdown @lexical/list @lexical/rich-text @lexical/selection @lexical/utils

Tạo Trình Soạn Thảo Cơ Bản

Hãy cùng tạo một trình soạn thảo cơ bản:

javascript Copy
import {
  createEditorSystem,
  boldExtension,
  italicExtension,
  historyExtension,
  listExtension,
  linkExtension,
  RichText,
} from "@lexkit/editor";
import "./basic-editor.css";

// 1. Định nghĩa các tiện ích mở rộng (để đảm bảo an toàn kiểu)
const extensions = [
  boldExtension,
  italicExtension,
  listExtension,
  linkExtension,
  historyExtension,
] as const;

// 2. Tạo hệ thống trình soạn thảo an toàn kiểu
const { Provider, useEditor } = createEditorSystem<typeof extensions>();

Điều thú vị là useEditor hoàn toàn an toàn kiểu - nó biết chính xác các lệnh mà bạn đã định nghĩa.

Ví Dụ Về Thanh Công Cụ

Dưới đây là một thanh công cụ đơn giản với một số hành động định dạng văn bản:

javascript Copy
// Thành phần Thanh Công Cụ - Hiển thị các nút định dạng văn bản cơ bản
function Toolbar() {
  const { commands, activeStates } = useEditor();

  return (
    <div className="basic-toolbar">
      <button
        onClick={() => commands.toggleBold()}
        className={activeStates.bold ? "active" : ""}
        title="Bold (Ctrl+B)"
      >
        Bold
      </button>
      <button
        onClick={() => commands.toggleItalic()}
        className={activeStates.italic ? "active" : ""}
        title="Italic (Ctrl+I)"
      >
        Italic
      </button>
      <button
        onClick={() => commands.toggleUnorderedList()}
        className={activeStates.unorderedList ? "active" : ""}
        title="Bullet List"
      >
        • Danh Sách
      </button>
      <button
        onClick={() => commands.toggleOrderedList()}
        className={activeStates.orderedList ? "active" : ""}
        title="Numbered List"
      >
        1. Danh Sách
      </button>
      <button
        onClick={() => commands.undo()}
        disabled={!activeStates.canUndo}
        className={!activeStates.canUndo ? "disabled" : ""}
        title="Undo (Ctrl+Z)"
      >
        ↶ Hoàn Tác
      </button>
      <button
        onClick={() => commands.redo()}
        disabled={!activeStates.canRedo}
        className={!activeStates.canRedo ? "disabled" : ""}
        title="Redo (Ctrl+Y)"
      >
        ↷ Làm Lại
      </button>
    </div>
  );
}

Kết Hợp Mọi Thứ Lại

Bây giờ, hãy sử dụng Toolbar trong trình cung cấp trình soạn thảo:

javascript Copy
// Thành phần Chính
export function BasicEditorExample() {
  return (
    <Provider extensions={extensions}>
      <div className="basic-editor">
        <Toolbar />
        <RichText
          classNames={{
            container: "basic-editor-container",
            contentEditable: "basic-content",
            placeholder: "basic-placeholder",
          }}
          placeholder="Bắt đầu viết nội dung của bạn ở đây..."
        />
      </div>
    </Provider>
  );
}

Để tạo kiểu cho nó, chỉ cần sao chép CSS dưới đây vào dự án của bạn:
👉 basic-editor.css

🎉 Bạn đã có trình soạn thảo đầu tiên chạy rồi!

Hãy thử nghiệm trực tiếp trong Playground.

Mẫu

Tương tự như cách chúng ta đã tạo trình soạn thảo cơ bản, bạn có thể nhập thêm các tiện ích mở rộng hoặc sử dụng các mẫu có sẵn:

  • Mẫu Mặc Định (React + CSS):
    👉 Mẫu Mặc Định LexKit
  • Mẫu Sẵn Sàng Shadcn:
    👉 Mẫu Lexical + Shadcn với LexKit

Tài Liệu & Trình Diễn

Tất cả đều được tài liệu hóa tại đây:

  • Trình Diễn Mẫu
  • Tài Liệu

Thực Hành Tốt Nhất

  • Sử dụng LexKit để giảm thiểu mã lặp lại và cải thiện khả năng bảo trì.
  • Kiểm tra tính năng trên nhiều trình duyệt khác nhau để đảm bảo tính tương thích.

Cạm Bẫy Thường Gặp

  • Chú ý đến các vấn đề hiệu suất khi sử dụng nhiều tiện ích mở rộng.
  • Đảm bảo rằng các kiểu CSS không bị xung đột với các thành phần khác trong ứng dụng của bạn.

Mẹo Hiệu Suất

  • Sử dụng lazy loading cho các tiện ích mở rộng không cần thiết ngay từ đầu.
  • Tối ưu hóa mã để giảm thiểu thời gian tải của trình soạn thảo.

Khắc Phục Sự Cố

  • Nếu gặp lỗi trong quá trình biên dịch, hãy kiểm tra lại các gói đã cài đặt và đảm bảo tất cả đều tương thích với nhau.

💡 Với LexKit, bạn có thể xây dựng các trình soạn thảo giống như Notion, trình soạn thảo blog, nhập liệu CMS hoặc bất kỳ RTE tùy chỉnh nào - tất cả trong khi vẫn giữ an toàn kiểu và thân thiện với React. Nếu bạn yêu thích React và TypeScript, tôi nghĩ bạn sẽ thích nó ❤️. Hãy cho tôi biết suy nghĩ của bạn. Đừng ngần ngại để lại bình luận <3

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào