美文网首页
NextJS开发:nextjs中使用CkEditor5

NextJS开发:nextjs中使用CkEditor5

作者: ArslanRobot | 来源:发表于2023-11-19 11:23 被阅读0次

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

    相关文章

      网友评论

          本文标题:NextJS开发:nextjs中使用CkEditor5

          本文链接:https://www.haomeiwen.com/subject/xhfmwdtx.html