NextJS开发:nextjs中使用CkEditor5

news/2024/7/15 19:47:46 标签: react.js, nextjs

NextJS项目中需要使用CkEditor5作为富文本编辑器,按照官网React CkEditor5手册使用出现如下错误:

node_modules/@ckeditor/ckeditor5-react/dist/index.js (5:242) @ eval
 ⨯ ReferenceError: self is not defined

还是因为nextjs的服务器端渲染造成的错误,富文本编辑器一般用在表单提交页面,没有使用ssr的必要,想要解决上面问题,动态导入组件,禁用ssr就可以解决。

1、封装ckeditor组件

"use client"

import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';

export function CustomCkEditor(props: {data: string, onChange: (content: string)=>void}) {
  
  const editorConfiguration = {
    toolbar: [
      'heading', //类型
      '|',
      'bold', //加粗
      'italic', //斜体
      'link', //超链接
      'bulletedList',// 无序列表
      'numberedList', //有序列表
      '|',
      'indent', //左缩进
      'outdent', //右缩进
      '|',
      'imageUpload', //图片上传
      'blockQuote', //引用
      'insertTable', //插入图标
      //'mediaEmbed', //视频上传
      'undo', //撤销
      'redo'//重做
    ]
  };

  return (
    <CKEditor
        config={ editorConfiguration }
        editor={ ClassicEditor }
        data={ props.data }
        onReady={ editor => {
            // You can store the "editor" and use when it is needed.
            console.log( 'Editor is ready to use!', editor );
        } }
        onChange={ ( event, editor ) => {
            const data = editor.getData();
            props.onChange(data)
            console.log( { event, editor, data } );
        } }
        onBlur={ ( event, editor ) => {
            console.log( 'Blur.', editor );
        } }
        onFocus={ ( event, editor ) => {
            console.log( 'Focus.', editor );
        } }
      />
  )
}

2、动态导入的Form组件

"use client"

import React from "react";
import { CustomCkEditor } from "@/components/app/custom-ckeditor";
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"

export function ReleaseForm(props: {}) 
{

  const [title, setTitle] = React.useState("");
  const [content, setContent] = React.useState("");
  
  const buildCkEditor = () => {
    return (
      <div className="release-ckeditor w-full overflow-visible text-black">
        <CustomCkEditor data={content} onChange={(data: string)=>setContent(data)}/>
      </div>
    )
  }

  const handleSubmit = () => {
    
  }

  return (
    <>
      <div className="mx-auto mt-5 lg:w-4/5 overflow-visible p-10 bg-white dark:bg-gray-900">
        <div className="text-lg font-bold">发布帖子</div>
        <div className="w-full mt-5">
          <Label className=" text-base ">标题 <span className="ml-2 text-xs">(最多60)</span></Label>
          <Input value={title} placeholder="请输入标题" className="mt-1 focus-visible:ring-0" onChange={(e)=>{setTitle(e.target.value)}}/>
          <div className="h-4 text-red-600 text-xs mt-1"></div>
        </div>
 
        <Label className=" text-base">内容</Label>
        <div className=" h-1"></div>
        {
          buildCkEditor()
        }

        <div className="w-full text-center">
          <Button className="mt-8 w-28" onClick={handleSubmit}>提交</CustomButton>
        </div>
      </div>
    </>
  )
}

3、导入Form、禁用ssr

"use client"
import React from "react";
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { CustomButton } from "@/components/app/custom-button";
import { ReleasePropsDialog } from "./(components)/release-props-dialog";

import dynamic from 'next/dynamic'
import { KeyPair } from "@/define/type";
//import { ReleaseForm } from "./(components)/release-form";

export default function ForumReleasePage({ params }: { params: { topic: string } }) {
  
  //动态导入,禁用ssr,否则报错ReferenceError: self is not defined
  const ReleaseForm = dynamic(() => import('./(components)/release-form').then((mod) => mod.ReleaseForm), { ssr: false })

  return (
    <>
      <ReleaseForm/>
    </>
  )
}

注意:这里之所以把所有表单界面和表单业务操作封装到ReleaseForm组件内,是因为测试发现如果只是直接动态导入CustomCkEditor,当绑定的内容改变,动态组件就会重新加载刷新出现闪烁现象


http://www.niftyadmin.cn/n/5197485.html

相关文章

一、zabbix 5.0 部署

zabbix 5.0版本为长期支持版本&#xff0c;安装方式封装成都更高&#xff0c;web ui更加细致&#xff0c;喜人&#xff0c;本篇记录zabbix5.0安装细节 官方部署文档&#xff0c;同样简单好用 1、安装yum源 [rootzabbix-server ~]# yum install -y https://repo.zabbix.com/zab…

【探索嵌入式虚拟化技术与应用】— 虚拟化技术深入浅出自学系列

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:【探索嵌入式虚拟化技术与应用】&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 一、虚拟技术的发展历史 1.1传统技术的局限性&#xff1a; ​编辑 1.2云计算和万物互联技术的发展机遇&#x…

【django+vue】连接数据库、登录功能

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【djangovue专栏】 1.【djangovue】项目搭建、解决跨域访问 【djangovue】连接数据库、登录功能 django连接数据库1.安装MySQL驱动程序2.创建数据库3.配置settings.py文件4.创建表5.添加数据 登录功能1.django实现…

C语言验证哥德巴赫猜想(ZZULIOJ1093:验证哥德巴赫猜想(函数专题))

题目描述 哥德巴赫猜想大家都知道一点吧。我们现在不是想证明这个结论&#xff0c;而是对于任给的一个不小于6的偶数&#xff0c;来寻找和等于该偶数的所有素数对。做好了这件实事,就能说明这个猜想是成立的。 要求程序定义一个prime()函数和一个main()函数&#xff0c;prime()…

【邻接表特点,邻接表的代码实现】

文章目录 邻接表特点邻接矩阵和邻接表表示法的关系 邻接表&#xff08;Adjacency List&#xff09; 是图的一种链式存储结构。 #include<iostream> using namespace std;#define MVNum 100 //最大顶点数 #define OtherInfo int //权值 #define VerTexType int//顶点的指针…

Java8实战-总结48

Java8实战-总结48 CompletableFuture&#xff1a;组合式异步编程对多个异步任务进行流水线操作实现折扣服务使用 Discount 服务 CompletableFuture&#xff1a;组合式异步编程 对多个异步任务进行流水线操作 实现折扣服务 你的“最佳价格查询器”应用现在能从不同的商店取得…

洛谷 P4568 [JLOI2011] 飞行路线 pytho解析

P4568 [JLOI2011] 飞行路线 pytho解析 时间&#xff1a;2023.11.20 题目地址&#xff1a;[JLOI2011] 飞行路线 题目分析 对于这个题呢就是最短路的问题了。那就可以用Dijkstra 算法&#xff0c;唯一不同的地方就是有免费的机票次数&#xff0c;那我们就先不考虑这个&#xf…

python functools.wraps保留被装饰函数属性

作用 普通装饰器 &#xff0c;会覆盖函数名称&#xff0c;并且 会替换 函数 文档字符串 介绍 functools.wraps(wrapped[, assigned][, updated]) This is a convenience function for invoking partial(update_wrapper, wrappedwrapped, assignedassigned, updatedupdated) …