本节涵盖:
使用 NPM 或 Yarn 安装 TinyMCE React 集成
在 Bootstrap 对话框中使用 TinyMCE React 集成
配置编辑器
可用属性
apiKeylicenseKeycloudChanneldisabledreadonlyidinitinitialValueinlineonEditorChangeoutputFormat(已移除)pluginsrollbackscriptLoadingtagNametextareaNametoolbartinymceScriptSrcvaluetabIndex
将 TinyMCE React 组件用作非受控组件
将 TinyMCE React 组件用作受控组件
事件绑定
使用 NPM 或 Yarn 安装 TinyMCE React 集成
要安装 tinymce-react 包并将其保存到 package.json 中。
npm install @tinymce/tinymce-react
或使用 Yarn
yarn add @tinymce/tinymce-react
在 Bootstrap 对话框中使用 TinyMCE React 集成
要在 Bootstrap UI 对话框内部使用 TinyMCE React 集成,请向渲染编辑器的组件添加以下 React 效果钩子。此代码是必需的,因为 Bootstrap 会阻止来自对话框外部元素的 focusin 调用。
Bootstrap 5
对于 Bootstrap 5,React 效果钩子不包含 JQuery。
useEffect(() => {
const handler = (e) => {
if (e.target.closest(".tox-tinymce-aux, .moxman-window, .tam-assetmanager-root") !== null) {
e.stopImmediatePropagation();
}
};
document.addEventListener("focusin", handler);
return () => document.removeEventListener("focusin", handler);
}, []);Bootstrap 4
useEffect(function() {
var handler = function(e) {
if ($(e.target).closest(".tox-tinymce, .tox-tinymce-aux, .moxman-window, .tam-assetmanager-root").length) {
e.stopImmediatePropagation();
}
};
$(document).on('focusin', handler);
return function() {
$(document).off('focusin', handler);
};
}, []);配置编辑器
tinymce-react 组件提供以下属性的 props:
配置编辑器源
配置页面元素
配置编辑器选项
管理编辑器
配置编辑器源
tinymce-react 集成将按以下顺序尝试获取 TinyMCE 源:
如果页面上存在全局
tinymce,则使用该tinymce。如果提供了
tinymceScriptSrcprop,则将向页面添加一个脚本标签,以便从给定的 URL 加载 TinyMCE。如果上述条件均不适用,则将向页面添加一个脚本标签,以便从 Tiny Cloud 加载 TinyMCE。
以下 props 用于配置如何获取编辑器源:
apiKeyTiny Cloud API 密钥。当从 Tiny Cloud 加载时,使用此 prop 以移除“继续使用 TinyMCE 需要有效的 API 密钥。请通知管理员检查当前 API 密钥。点击此处了解更多。”警告消息。
licenseKeyTiny Cloud 许可密钥。如果您自行托管 TinyMCE 而不是从 Tiny Cloud 加载时使用此密钥。
cloudChannel当从 Tiny Cloud 加载时使用的 TinyMCE 通道。
scriptLoading脚本加载行为 prop。允许设置 async 和 defer 属性,以及添加额外的毫秒延迟。
tinymceScriptSrc当加载自托管版本的 TinyMCE 时用于获取 TinyMCE 的 URL。
配置页面元素
这些 props 提供一些对集成创建的页面元素的控制:
id编辑器初始化所在元素的 id 属性。
inline将编辑器作为页面的一部分加载;共享页面样式和选择范围。
tagName用于创建内联编辑器的标签。对于经典(iframe)编辑器将被忽略。
textareaNametextarea 标签(HTML 元素)的 name 属性。用于创建经典(iframe)编辑器。对于内联编辑器将被忽略。
配置编辑器选项
这些 props 在编辑器初始化时被读取。编辑器启动后的更改将被忽略。
init传递给 TinyMCE 的附加选项,在其初始化时生效。
plugins指定编辑器插件。这将与 init prop 中的 plugins 合并。
toolbar指定编辑器工具栏。这将覆盖 init prop 中的 toolbar。
管理编辑器
这些 props 可以在编辑器初始化后更新。注意此处未提及其它事件。
disabled是否禁用编辑器。
readonly是否将编辑器设置为只读模式。
initialValue编辑器的初始值。在编辑器加载后更改此值将重置编辑器(包括编辑器内容)。
onBeforeAddUndo一个事件处理器,用于通知何时即将创建撤销级别,并在需要时阻止它。这对于限制编辑器允许值的受控组件非常重要。
onEditorChange一个事件处理器,用于检测编辑器更改。在将 TinyMCE 实现为受控组件时非常有用。
onInit一个事件处理器,用于通知编辑器已初始化。适用于获取编辑器的初始值或获取可用于非受控组件的编辑器引用。
value设置并强制执行编辑器的值。仅用于受控组件。
value设置编辑器包裹的目标元素的 tabindex。
可用 props
TinyMCE React 组件不需要任何配置 props;但是,如果从 Tiny Cloud 加载时未配置 apiKey prop,编辑器中将显示警告消息。关于使用哪些 props 的指导,请参阅:配置编辑器。
apiKey
Tiny Cloud API 密钥。
对于使用 Tiny Cloud 部署以提供 TinyMCE 编辑器且不希望显示警告消息"A valid API key is required to continue using TinyMCE. Please alert the admin to check the current API key. Click here to learn more"的情况,此密钥是必需的。
要注册 Tiny Cloud API 密钥,请访问 Tiny Account 注册页面。要为现有的 Tiny Account 检索 Tiny Cloud API 密钥,请登录并访问 Tiny Account 仪表板。
类型: String
默认值: 'no-api-key'
示例:使用 apiKey
<Editor apiKey='no-api-key' />
licenseKey
指定 TinyMCE 许可密钥。对于 TinyMCE 的自托管部署是必需的。对于仅使用 Tiny Cloud 的云部署,此属性不是必需的,因为您的云订阅自动包含商业许可。更多信息,请参阅:License Key。
类型: String
默认值: undefined
可能值:* undefined - 当使用 API 密钥从 Tiny Cloud 加载时使用* 'gpl' - 用于使用 GPL 许可的开源项目* 'T8LK:…' - 用于商业 TinyMCE 安装(版本 8+ 必须使用此前缀)* 'GPL+T8LK:' - 用于需要高级功能但需保持 GPL 合规性的开源项目。
在混合部署(同时使用云和自托管功能)中:
您可以同时提供 API 密钥和许可密钥
编辑器将在可用时使用云服务
如果无法联系云服务,它将自动回退到本地许可密钥
示例:商业许可
<Editor licenseKey='T8LK:...' />
示例:使用带有 GPL 的 licenseKey
<Editor licenseKey='gpl' />
cloudChannel
更改用于编辑器的 TinyMCE 构建版本,可以是特定版本或表示稳定级别的通道。
类型: String
默认值: '8'
可能值: '8', '8-testing', '8-dev', '8.10'
更改用于编辑器的 TinyMCE 构建版本,使其为以下 Tiny Cloud 频道之一:
8(默认值):TinyMCE 当前的企业版发布。8-testing:TinyMCE 下一代企业版发布的当前候选版本。8-dev:TinyMCE 的夜间构建版本。版本号,例如
8.10:TinyMCE 特定的企业版发布版本。
例如:
<Editor
apiKey='no-api-key'
cloudChannel='8-dev'
init={{ /* your other settings */ }}
/>有关 TinyMCE 开发频道的信息,请参阅:指定从 Cloud 部署的 TinyMCE 编辑器版本 - dev、testing 和 stable 发布。
disabled
disabled 属性可以动态切换编辑器的禁用状态。
类型: Boolean
默认值: false
可能值: true, false
示例:使用 disabled
<Editor
disabled={true}
/>readonly
readonly 属性可以在只读模式(true)和标准可编辑模式(false)之间动态切换编辑器。
类型: Boolean
默认值: false
可能值: true, false
示例:使用 readonly
<Editor
readonly={true}
/>id
编辑器的 ID。用于通过 tinymce.get('ID') 方法检索编辑器实例。
类型: String
默认值: 自动生成 UUID
示例:使用 id
<Editor id='your-id' />
init
传递给 tinymce.init({...}) 方法的附加设置,该方法用于初始化编辑器。
有关 TinyMCE tinymce.init({...}) 方法的信息,请参阅:基本设置。
当使用 tinymce-react 时:
init属性不需要selector或target选项。如果使用
init属性设置了selector、target、readonly或license_key选项,它们将被集成覆盖。
类型: Object
默认值: { }
示例:使用 init
<Editor
init={{
plugins: 'lists link image paste help wordcount',
toolbar: 'undo redo | blocks | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | help'
}}
/>initialValue
编辑器的初始 HTML 内容。更改此值将重置编辑器的撤销状态和光标位置。
可以在编辑器加载之前设置,也可以在随后由异步过程设置。
请确保此值不要通过 onEditorChange 更新,否则编辑器将无法使用。类型: String
默认值: ''
示例:使用静态 initialValue
<Editor initialValue='<p>Once upon a time...</p>' />
示例:使用异步 initialValue
const [initialValue, setInitialValue] = useState(undefined);
useEffect(() => {
// 实际应用中可能会在此处执行 fetch 请求以获取内容
setTimeout(() => setInitialValue('<p>Once upon a time...</p>'), 500);
}, []);
return (
<Editor
initialValue={initialValue}
/>
);inline
用于将编辑器设置为内联模式。使用 <Editor inline={true} /> 等同于在 TinyMCE tinymce.init({...}) 方法中设置 {inline: true}。
有关内联模式的信息,请参见:用户界面选项 - inline 和 设置内联编辑模式。
类型: Boolean
默认值: false
可能值: true, false
示例:使用 inline
<Editor
inline={true}
/>onEditorChange
用于在 TinyMCE React 组件外部存储编辑器状态。当将 TinyMCE React 组件用作受控组件时,通常会使用此属性。
它接收两个参数:
value编辑器的当前值。这是 HTML 格式。
editor对编辑器的引用。
有关使用 onEditorChange 的详细信息,请参见:将 TinyMCE React 组件用作受控组件。
类型: EventHandler
outputFormat (已移除)
此选项已在 TinyMCE React 组件 4.0.0 版本发布时被移除。
此选项用于指定由onEditorChange事件生成的内容的格式,但由于它不改变输入格式,因此几乎无法正确使用。
示例:替换 outputFormat 的使用
const [value, setValue] = useState('<p>The quick brown fox jumps over the lazy dog</p>');
const [text, setText] = useState('');
return (
<>
<Editor
value={value}
onInit={(evt, editor) => {
setText(editor.getContent({format: 'text'}));
}}
onEditorChange={(newValue, editor) => {
setValue(newValue);
setText(editor.getContent({format: 'text'}));
}}
/>
<pre>{text}</pre>
</>
);plugins
用于包含编辑器的插件。使用 <Editor plugins='lists' /> 等同于在 TinyMCE tinymce.init({...}) 方法中设置 {plugins: 'lists'}。
有关向 TinyMCE 添加插件的信息,请参见:向 TinyMCE 添加插件。
类型: String 或 Array
示例:使用 plugins
<Editor plugins='lists code' />
rollback
用于配置回滚计时器。这是在 onEditorChange 属性发出事件与强制应用 value 属性之间的毫秒数。
当 rollback 为 false 时,除非 value 属性发生变化,否则不会强制应用该属性。
类型: Number 或 false
默认值: 200
示例:使用 rollback
<Editor
rollback={0}
value="<p>This value will be restored almost as soon as it is changed.</p>"
/>scriptLoading
用于配置用于加载 TinyMCE 的 script 标签。
类型: Object
type ScriptLoading = {
async?: boolean;
defer?: boolean;
delay?: number;
};包含 3 个设置:
async设置在用于加载 TinyMCE 的 script 标签上的 async 属性。
对于传统脚本,如果存在 async 属性,则传统脚本将与解析并行获取,并在可用时立即执行。— https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-async
类型: Boolean
默认值: false
defer设置在用于加载 TinyMCE 的 script 标签上的 defer 属性。
此 Boolean 属性用于指示浏览器在文档解析完成后但在触发 DOMContentLoaded 之前执行脚本。— https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attr-defer
类型: Boolean
默认值: false
delay将在指定的毫秒延迟后添加用于加载 TinyMCE 的 script 标签。
类型: Number
默认值: 0
示例:异步加载 TinyMCE
<Editor scriptLoading={{ async: true }}>示例:延迟 500 毫秒加载 TinyMCE
<Editor scriptLoading={{ delay: 500 }}>tagName
仅在 <Editor inline={true} /> 时有效。用于定义内联模式下编辑器的 HTML 元素。
类型: String
默认值: 'div'
示例:使用 tagName
<Editor
inline={true}
tagName='section'
/>textareaName
仅在编辑器处于经典(iframe)模式时有效。设置表单中用于编辑器的 textarea 元素的 name 属性。
类型: String
示例:使用 textareaName
<form method="post">
<Editor
textareaName='description'
/>
<button type="submit">提交</button>
</form>toolbar
用于设置编辑器的工具栏。使用 <Editor toolbar='bold' /> 等同于在 TinyMCE 方法 tinymce.init({...}) 中设置 {toolbar: 'bold'}。
有关设置 TinyMCE 工具栏的信息,请参阅:用户界面选项 - 工具栏。
类型: String
可能值: 请参阅 TinyMCE 可用的工具栏按钮。
示例:使用 toolbar
<Editor plugins='code' toolbar='bold italic underline code' />
tinymceScriptSrc
使用 tinymceScriptSrc 属性指定要懒加载的 TinyMCE 外部版本。
类型: String
示例:使用 tinymceScriptSrc
<Editor tinymceScriptSrc='/path/to/tinymce.min.js' />
value
当作为受控组件运行时,设置编辑器的 HTML 内容。
当此属性与当前编辑器内容不同时,编辑器内容将在 200 毫秒内更改以匹配,并创建一个撤销级别。当通过此机制更改编辑器内容时,编辑器将尝试保留选择状态,但如果新内容中不存在之前的选择,光标将返回到文档开头。
此属性允许通过设置 value 属性并使用 onEditorChange 事件更新 value 来将编辑器用作受控组件。
有关使用 value 属性的详细信息,请参阅:将 TinyMCE React 组件用作受控组件。
类型: String
tabIndex
使用 tabIndex 属性设置编辑器包装的目标元素的 tabindex。
类型: Number
示例:使用 tabIndex
<Editor
tabIndex={-1}
/>将 TinyMCE React 组件用作非受控组件
TinyMCE React 组件设计为用作非受控组件,这允许编辑器在大型文档上表现良好。
当将编辑器用作非受控组件时,避免使用 value 和 onEditorChange 属性。Tiny 建议在需要时检索编辑器内容。可以使用 onInit 事件处理器在编辑器加载时存储编辑器引用,以帮助检索内容。
为了在内容准备好保存时向用户提供视觉反馈,请使用 onDirty 事件处理器;并结合在保存编辑器内容时清除编辑器的“脏”状态。
当用户在初始化或最后一次 tinymce.editor.save() 调用后修改编辑器内容时,编辑器处于“脏”(或“脏”状态)。这包括使用撤销或重做所做的更改。示例:带有保存按钮和脏状态的函数式非受控组件
function MyComponent({initialValue}) {
const editorRef = useRef(null);
const [dirty, setDirty] = useState(false);
useEffect(() => setDirty(false), [initialValue]);
const save = () => {
if (editorRef.current) {
const content = editorRef.current.getContent();
setDirty(false);
editorRef.current.setDirty(false);
// an application would save the editor content to the server here
console.log(content);
}
};
return (
<>
<Editor
initialValue={initialValue}
onInit={(evt, editor) => editorRef.current = editor}
onDirty={() => setDirty(true)}
/>
<button onClick={save} disabled={!dirty}>Save</button>
{dirty && <p>You have unsaved content!</p>}
</>
);
}将 TinyMCE React 组件作为受控组件使用
受控组件在处理大文档时可能存在性能问题,因为它需要在每次按键或修改时将整个文档转换为字符串。
要将编辑器用作 受控组件,必须同时提供 value 和 onEditorChange 属性。
value 属性用于设置和重置编辑器内容。如果未将其更新为编辑器内容的最新版本,编辑器将回滚任何更改。
onEditorChange 属性用于提供一个事件处理程序,该处理程序将在对编辑器内容进行任何更改时运行。为了防止更改被回滚,编辑器的更改必须在 200 毫秒 内应用到 value 属性。
示例:函数式受控组件
function MyComponent({initialValue}) {
const [value, setValue] = useState(initialValue ?? '');
useEffect(() => setValue(initialValue ?? ''), [initialValue]);
return (
<Editor
initialValue={initialValue}
value={value}
onEditorChange={(newValue, editor) => setValue(newValue)}
/>
);
}示例:类式受控组件
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { value: props.initialValue ?? '' };
this.handleEditorChange = this.handleEditorChange.bind(this);
}
componentDidUpdate(prevProps) {
if (this.props.initialValue !== prevProps.initialValue) {
this.setState({ value: this.props.initialValue ?? '' })
}
}
handleEditorChange(value, editor) {
this.setState({ value });
}
render() {
return (
<Editor
initialValue={this.props.initialValue}
value={this.state.value}
onEditorChange={this.handleEditorChange}
/>
)
}
}当必须限制编辑器以避免无效状态(例如超过最大长度)时,必须添加 onBeforeAddUndo 的处理程序,以防止这些状态出现在撤销历史中。
示例:有限长度的受控组件
function MyComponent({initialValue, limit}) {
const sizeLimit = limit ?? 50;
const [ value, setValue ] = React.useState(initialValue ?? '');
const [ length, setLength ] = React.useState(0);
const handleInit = (evt, editor) => {
setLength(editor.getContent({ format: 'text' }).length);
};
const handleUpdate = (value, editor) => {
const length = editor.getContent({ format: 'text' }).length;
if (length <= sizeLimit) {
setValue(value);
setLength(length);
}
};
const handleBeforeAddUndo = (evt, editor) => {
const length = editor.getContent({ format: 'text' }).length;
// note that this is the opposite test as in handleUpdate
// because we are determining when to deny adding an undo level
if (length > sizeLimit) {
evt.preventDefault();
}
};
return (
<>
<Editor
initialValue={initialValue}
value={value}
onInit={handleInit}
onEditorChange={handleUpdate}
onBeforeAddUndo={handleBeforeAddUndo}
/>
<p>Remaining: {sizeLimit - length}</p>
</>
);
};有关 React 中受控组件的信息,请参阅:React 文档 - 受控组件。
事件绑定
可以将函数绑定到编辑器事件,例如:
<Editor onSelectionChange={this.handlerFunction} />当调用处理程序时(本例中的 handlerFunction),它将带有两个参数被调用:
eventTinyMCE 事件对象。
editor编辑器的引用。
以下事件可用:
onActivateonAddUndoonBeforeAddUndoonBeforeExecCommandonBeforeGetContentonBeforeRenderUIonBeforeSetContentonBeforePasteonBluronChangeonClearUndosonClickonContextMenuonCompositionEndonCompositionStartonCompositionUpdateonCopyonCutonDblclickonDeactivateonDirtyonDragonDragDroponDragEndonDragGestureonDragOveronDroponExecCommandonFocusonFocusInonFocusOutonGetContentonHideonInitonInputonKeyDownonKeyPressonKeyUponLoadContentonMouseDownonMouseEnteronMouseLeaveonMouseMoveonMouseOutonMouseOveronMouseUponNodeChangeonObjectResizeStartonObjectResizedonObjectSelectedonPasteonPostProcessonPostRenderonPreProcessonProgressStateonRedoonRemoveonResetonSaveContentonSelectionChangeonSetAttribonSetContentonShowonSubmitonUndoonVisualAid