nextjs中怎么正确使用@wangEditor富文本

背景

实现一个博客主站的文章生成系统,使用ssr去生成自己的文章,达到seo的效果。

技术栈

使用

  1. 引入富文本编辑器 npm i -S @wangeditor/editor @wangeditor/editor-for-react

  2. 基本的组件引入 src/app/components/rich-text/index.tsx 需要开启use client 可以试试不开,最后会贴上碰到的问题,以及解决方案

typescript 复制代码
// 不加报错 useState only works in Client Components. Add the "use client" directive at the top of the file to use it
'use client'
import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
import '@wangeditor/editor/dist/css/style.css';
import React, { useEffect, useState } from 'react';
import './index.scss';

export interface IRichTextProps {
  /**
   * 富文本内容
   * @default ''
   */
  defaultContent?: string;
  /**
   * 富文本提示文字
   * @default '请输入内容'
   */
  placeholder?: string;
  /**
   * 富文本内容变化回调
   * @param html 富文本内容
   */
  onChange?: (html: string) => void;
}

export default function RichText(props: IRichTextProps) {
  const { defaultContent = '', placeholder = '请输入内容', onChange } = props;
  // editor 实例
  const [editor, setEditor] = useState<IDomEditor | null>(null);
  // 编辑器内容
  const [html, setHtml] = useState(defaultContent);
  // 工具栏配置
  const toolbarConfig: Partial<IToolbarConfig> = {};
  // 编辑器配置
  const editorConfig: Partial<IEditorConfig> = {
    placeholder
  };
  // 及时销毁 editor ,重要!
  useEffect(() => {
    return () => {
      if (editor === null) return;
      editor.destroy();
      setEditor(null);
    };
  }, [editor]);

  const handleChange = (editor: IDomEditor) => {
    const h = editor.getHtml();
    setHtml(h);
    onChange && onChange(h);
  };    

  return (
    <>
      <div style={{ border: '1px solid #ccc', zIndex: 100 }}>
        <Toolbar
          editor={editor}
          defaultConfig={toolbarConfig}
          mode="default"
          style={{ borderBottom: '1px solid #ccc' }}
        />
        <Editor
          defaultConfig={editorConfig}
          value={html}
          onCreated={setEditor}
          onChange={handleChange}
          mode="default"
        />
      </div>
    </>
  );
}
  1. 页面中的使用 目录: src/app/rich/page.tsx
typescript 复制代码
import dynamic from 'next/dynamic'
import { Metadata } from 'next';

// 关闭服务端渲染 否则报错 ReferenceError: Element is not defined
const RichText = dynamic(() => import("../components/rich-text"), {
  ssr: false,
});

export const metadata: Metadata = {
  title: '创建数据',
}

export default function CreateText() {
  return (
    <div className='a'>
        <RichText />
    </div>
  );
}
  1. 以上基本上代码层面没问题了,问题会出现在第三方插件和nextjs集成的一些地方

问题

针对性的说一下wangeditor和nextjs一起使用出现的问题

  1. TypeError: Cannot set property navigator of #<Object> which has only a getter 问题描述:nextjs内部对全局navigator对象通过重新定义api(defineProperty),该值被设置为不可更改,只能读;而wangeditor内部却在更改navigator这个值,导致报错提示 解决方案:找到node_modules中wangeditor/editor中dist的index.esm.js删除掉更改navigator的代码 ---- 后面会给出文件
  2. TypeError: t is not function 来自于@wangEditor/editor的报错 解决方案:找到对应报错的index.esm.js中的地方,处理一下代码即可 --- 后面会给出文件
  3. Cannot destructure property 'protocol' of 'window.location' as it is undefined. 问题描述:由问题1引发的问题,解决问题1即可
  4. ⨯ ReferenceError: Element is not defined 问题描述:由于在服务端渲染@wangEditor插件导致,按照上面代码使用,就不会出现此问题

以上的统一解决方案

核心思路:替换更改后的index.esm.js作为构建的资源, 打开下方在线编辑器-进入获取js文件内容

标题在根目录下创建scripts文件夹,然后新建run.sh
markdown 复制代码
`run.sh` *(这里博主以pnpm包管理器为例,如果你们是yarn和npm需要自己找到对应的依赖包做替换。)*
bash 复制代码
cp scripts/index.esm.js node_modules/.pnpm/@wangeditor+editor@5.1.23/node_modules/@wangeditor/editor/dist/index.esm.js
相关推荐
彭世瑜19 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40420 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish20 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five21 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序22 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54122 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
前端每日三省23 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
小刺猬_98524 分钟前
(超详细)数组方法 ——— splice( )
前端·javascript·typescript
渊兮兮25 分钟前
Vue3 + TypeScript +动画,实现动态登陆页面
前端·javascript·css·typescript·动画
鑫宝Code25 分钟前
【TS】TypeScript中的接口(Interface):对象类型的强大工具
前端·javascript·typescript