NextJS开发:nextjs中使用CkEditor5

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,当绑定的内容改变,动态组件就会重新加载刷新出现闪烁现象

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ArslanRobot

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值