我正在使用CKEditor5 React组件框架。我已经成功地将CKEditor集成到我的项目中。并且能够使用它。 但问题是我必须将编辑器的内容保存到数据库中,然后将其显示到网站上。我得到的都是内容
<blockquote><p>Hello from CKEditor 5!</p></blockquote>
显示时它不会应用 CkEditor 的 css 来显示..
CKEDITOR 的设置是
import React, { Component } from 'react';
import CKEditor from '@ckeditor/ckeditor5-react';
import Classiceditor from '@ckeditor/ckeditor5-build-classic';
export class ClassicEditor extends Component {
constructor(){
super();
this.state = {
content : ""
}
}
onCashange = data => {
console.log( "Called" );
this.setState({
content : data.getData()
})
}
render() {
Classiceditor.builtinPlugins.map( plugin => console.log(plugin.pluginName) );
console.log("State", this.state.content);
return (
<>
<div className='App'>
<h2> Using CKEditor</h2>
<CKEditor
editor = { Classiceditor }
data = "<p>Hello from CKEditor 5!</p>"
onInit = { editor => {
//console.log( 'Editor is ready to use!', editor )
} }
onChange = { ( event, editor ) => {
this.onCashange( editor );
// const data = editor.getData();
// this.onChange( data );
// //console.log( { event, editor, data } );
}}
onBlur = { editor =>
console.log("Blur", editor) }
onFocus = { editor => {
//console.log( "Focus", editor )
} }
/>
</div>
<div className='editor'>
{ this.state.content }
</div>
</>
)
}
}
export default ClassicEditor
React 不允许您直接渲染
html
代码。相反,您必须使用 dangerouslySetInnerHTML
属性来执行此操作。请执行以下操作来解决您的问题,
<div dangerouslySetInnerHTML={this.createMarkup()} className='editor'></div>
并且在类上有一个方法作为
createMarkup = () => {
return { __html: this.state.content };
}
这将确保您不会将原始 HTML 渲染到页面。
您可以在这里阅读更多相关信息
你可以像
npm i react-render-html
一样安装npm包
在此输入链接描述
并像这样使用它:
<div className='...'>
{renderHTML(someHTML)}
</div>
以上问题的答案如下:
<div style={{wordWrap:'break-word',display:'inline-block'}}>
<div className="editor" dangerouslySetInnerHTML={{_html:this.state.content}}/>
</div>
对于 2023 年阅读本文的任何人,我使用 Next.js 13.4.19 和 interweave 库提出了以下解决方案。这段代码将完全按照编辑器中显示的内容显示内容。我相信您可以使用您选择的任何 html 渲染库。该解决方案应该与任何其他流行的框架(如 React)一起使用。这里真正的技巧是:
content.module.css
- 您可以将此文件命名为任何您想要的名称,只需确保它有module
部分ck-content
类的容器中 - 否则 CSS 将不会被应用interweave
(或您选择的任何其他库)将其应用到具有 class
属性的组件,而无需创建新的 React 组件,因为它更简单。以下代码展示了一个 SSR 组件,因此开头有
polyfill();
。请注意,对于图像,您必须自己处理正确的源填充,因为内容可能来自外部源,例如 CMS。我认为,最简单的解决方案是从节点获取属性并将其粘贴到组件中。
import { Markup, Node } from "interweave";
import { polyfill } from 'interweave-ssr';
import Image from "next/image";
import styles from "@/app/styles/richtext.module.scss"
import React from "react";
polyfill();
function transform(node: HTMLElement, children: Node[]): React.ReactNode {
const cls = node.getAttribute("class")
if (node.tagName == "img") {
const imgUrl = computeImageSource() // YOU HANDLE THIS YOURSELF
return (
<Image
src={imgUrl || ""}
alt={node.getAttribute("alt") || "none provided"}
width={0}
height={0}
sizes="100vw"
layout="responsive"
loading='eager'
/>
)
} else if (cls) {
node.setAttribute("class", cls.split(" ").map(c => styles[c]).join(" "))
return undefined;
}
}
export default function Content({ data }: { data: any }) {
// console.log(data)
return (
<section>
<Markup content={data} transform={transform} className={styles["ck-content"]} />
</section>
);
}
cls.split(" ").map(c => styles[c]).join(" ")
行很重要,因为它告诉 Next.js 从样式表应用适当的 CSS 类。