论坛定制/seo的主要工作内容
前言:wangEditor 官网 。本文档讲解 wangEditor 在 vue3 中的使用。
一:快速开始
1. 安装
需要安装 @wangeditor/editor、@wangeditor/editor-for-vue@next 两个依赖
# 安装 editor
npm install @wangeditor/editor
# or
yarn add @wangeditor/editor
# or
pnpm add @wangeditor/editor# 安装 Vue3 组件
npm install @wangeditor/editor-for-vue@next
# or
yarn add @wangeditor/editor-for-vue@next
# or
pnpm add @wangeditor/editor-for-vue@next
2. 构建组件 components/Rich.vue
<script setup lang="ts">import "@wangeditor/editor/dist/css/style.css"; // 引入 cssimport { onBeforeUnmount, ref, shallowRef, computed } from "vue";import { Editor, Toolbar } from "@wangeditor/editor-for-vue";const props = defineProps({modelValue: {type: String,required: true,},toolbarConfig: {type: Object,default: {},},editorConfig: {type: Object,default: {placeholder: "请输入内容...",},},height: {type: String,default: "300px",},});const emits = defineEmits(["update:modelValue"]);let valueHtml = computed({get() {return props.modelValue;},set(value) {emits("update:modelValue", value);},});let style: any = computed(() => {return {height: props.height,"overflow-y": "hidden",};});// 编辑器实例,必须用 shallowRefconst editorRef = shallowRef();// 模式let mode = ref("default");// 组件销毁时,也及时销毁编辑器onBeforeUnmount(() => {const editor = editorRef.value;if (editor == null) return;editor.destroy();});const handleCreated = (editor: any) => {editorRef.value = editor; // 记录 editor 实例,重要!};
</script><template><div class="editor-content-view"><Toolbarstyle="border-bottom: 1px solid #ccc":editor="editorRef":defaultConfig="toolbarConfig":mode="mode"/><Editor:style="style"v-model="valueHtml":defaultConfig="editorConfig":mode="mode"@onCreated="handleCreated"/></div>
</template><style lang="scss" scoped>.editor-content-view {border: 1px solid #ccc;z-index: 999;}
</style>
3. 使用 Rich.vue 组件
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");
</script><template><div class="page-rich"><Rich v-model="richHtml" /></div>
</template><style lang="scss" scoped></style>
二:优势
使用 slate.js(但不依赖 React)为内核、强稳定性、高扩展性、有详细中文文档、可直接使用无需二次开发、不依赖框架。
三:基础
1. 定义 CSS
可自定义编辑器、工具栏的尺寸、边框、z-index 等样式。
<template><!-- 边框 --><div class="editor-content-view"><!-- 工具栏 --><Toolbar style="border-bottom: 1px solid #ccc" /><!-- 编译器 --><Editor style="height: 500px; overflow-y: hidden" /></div>
</template><style lang="scss" scoped>.editor-content-view {border: 1px solid #ccc;z-index: 999;}
</style>
2. 定义 HTML
如果想要“全屏”功能,则要求工具栏、编辑器 DOM 节点必须是同一层级,同时父级盒子设置 z-index: 999。
<template><div class="editor-content-view"><!-- 工具栏 --><Toolbar /><!-- 编译器 --><Editor /></div>
</template><style lang="scss" scoped>.editor-content-view {z-index: 999;}
</style>
3. 模式
通过设置 mode 改变富文本模式,'default' 默认模式,基础所有功能。'simple' 简洁模式,仅有常用功能。
<script setup lang="ts">// 模式let mode = ref("default");
</script><template><div class="editor-content-view"><Toolbar :mode="mode" /><Editor :mode="mode" /></div>
</template>
四:在 vue3 中使用
1. 配置
可通过 toolbarConfig 和 editorConfig 来修改菜单栏和编辑器的配置。注意:编辑器配置中 onXxx 格式的生命周期函数,必须通过 Vue 事件来传递,不可以放在 editorConfig 中
<script setup lang="ts">const props = defineProps({toolbarConfig: {type: Object,default: {},},editorConfig: {type: Object,default: {placeholder: "请输入内容...",},},});const handleCreated = (editor: any) => {editorRef.value = editor; // 记录 editor 实例,重要!};
</script><template><div class="editor-content-view"><Toolbar :defaultConfig="toolbarConfig" /><Editor :defaultConfig="editorConfig" @onCreated="handleCreated" /></div>
</template><style lang="scss" scoped>.editor-content-view {border: 1px solid #ccc;z-index: 999;}
</style>
2. 调用 API
当编辑器渲染完成之后,通过 editorRef.value 获取 editor 实例,即可调用它的 API 。
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {const editor = editorRef.value;if (editor == null) return;editor.destroy();
});
五:配置和 API
下面代码例子,都是以 components/Rich.vue 作为例子的基础上扩展功能。
1. 工具栏配置
1.1 getConfig
通过 toolbar.getConfig() 查看工具栏的默认配置
import { DomEditor } from "@wangeditor/editor";const handleCreated = (editor) => {const toolbar = DomEditor.getToolbar(editor);const result = toolbar.getConfig();console.log(result);
};
1.2 toolbarKeys
重新配置工具栏,显示哪些菜单,以及菜单的排序、分组。可以通过 toolbar.getConfig().toolbarKeys 查看当前的默认配置。
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("asdf");let toolbarConfig = {toolbarKeys: [// 菜单 key"headerSelect",// 分割线"|",// 菜单 key"bold","italic",],insertKeys: {index: 1, // 插入的位置,基于当前的 toolbarKeyskeys: ["color", "bgColor"],},};
</script><template><div class="page-rich"><Rich v-model="richHtml" :toolbarConfig="toolbarConfig" /></div>
</template>
1.3 insertKeys
在当前 toolbarKeys 的基础上继续插入新菜单,如自定义扩展的菜单。
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("asdf");let toolbarConfig = {toolbarKeys: [// 菜单 key"headerSelect",// 分割线"|",// 菜单 key"bold","italic",],insertKeys: {index: 1, // 插入的位置,基于当前的 toolbarKeyskeys: ["color", "bgColor"],},};
</script><template><div class="page-rich"><Rich v-model="richHtml" :toolbarConfig="toolbarConfig" /></div>
</template>
1.4 excludeKeys
排除掉某些菜单
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("asdf");let toolbarConfig = {toolbarKeys: [// 菜单 key"headerSelect",// 分割线"|",// 菜单 key"bold","italic",],insertKeys: {index: 1, // 插入的位置,基于当前的 toolbarKeyskeys: ["color", "bgColor"],},excludeKeys: ["headerSelect"],};
</script><template><div class="page-rich"><Rich v-model="richHtml" :toolbarConfig="toolbarConfig" /></div>
</template>
2. 编辑器配置
2.1 getConfig
通过 editor.getConfig() 查看工具栏的默认配置
const handleCreated = (editor) => {const result = editor.getConfig();console.log(result);
};
2.2 editorConfig 配置
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({placeholder: "请输入",readOnly: false, // 是否只读,默认 falseautoFocus: true, // 是否focus, 默认 truescroll: true, // 是否支持滚动,默认true。不要固定 editor-container 的高度,设置一个 min-height 即可。maxLength: 20, // 最高内容长度,onMaxLength 当达到限制时,触发函数});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
2.3 编译器方法
<script setup lang="ts">// 编辑器创建完毕时的回调函数。const handleCreated = (editor) => {editorRef.value = editor;console.log("created", editor);};// 编辑器内容、选区变化时的回调函数。const handleChange = (editor) => {console.log("change:", editor.children);};// 编辑器销毁时的回调函数。调用 editor.destroy() 即可销毁编辑器const handleDestroyed = (editor) => {console.log("destroyed", editor);};// 编辑器 focus 时的回调函数。const handleFocus = (editor) => {console.log("focus", editor);};// 编辑器 blur 时的回调函数。const handleBlur = (editor) => {console.log("blur", editor);};// 自定义编辑器 alert 。const customAlert = (info, type) => {alert(`【自定义提示】${type} - ${info}`);};// 自定义粘贴。可阻止编辑器的默认粘贴,实现自己的粘贴逻辑。const customPaste = (editor, event, callback) => {console.log("ClipboardEvent 粘贴事件对象", event);// const html = event.clipboardData.getData('text/html') // 获取粘贴的 html// const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本// const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据(如从 word wsp 复制粘贴)// 自定义插入内容editor.insertText("xxx");// 返回 false ,阻止默认粘贴行为event.preventDefault();callback(false); // 返回值(注意,vue 事件的返回值,不能用 return)// 返回 true ,继续默认的粘贴行为// callback(true)};
</script><template><div class="editor-content-view"><Toolbar /><Editor@onCreated="handleCreated"@onChange="handleChange"@onDestroyed="handleDestroyed"@onFocus="handleFocus"@onBlur="handleBlur"@customAlert="customAlert"@customPaste="customPaste"/></div>
</template>
3. 菜单配置
各个菜单项的详细配置。
3.1 通用方法
要配置哪个菜单,首先要知道这个菜单的 key 。执行 editor.getAllMenuKeys() 可获取编辑器所有菜单,从中找到自己想要的菜单 key 即可。
const handleCreated = (editor) => {const result = editor.getAllMenuKeys();console.log(result);
};
找到菜单 key 之后,可以先看看菜单的当前配置,再自行修改。
const handleCreated = (editor) => {const result = editor.getMenuConfig("uploadImage"); // 获取 uploadImage 的当前配置console.log(result);
};
3.2 颜色
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({MENU_CONF: {color: {colors: ["#000", "#333", "#666"],},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.3 字号
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({MENU_CONF: {fontSize: {fontSizeList: [// 元素支持两种形式// 1. 字符串;// 2. { name: 'xxx', value: 'xxx' }"12px","16px",{ name: "24px", value: "24px" },"40px",],},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.4 字体
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({MENU_CONF: {fontFamily: {fontFamilyList: [// 元素支持两种形式// 1. 字符串;// 2. { name: 'xxx', value: 'xxx' }"黑体","楷体",{ name: "仿宋", value: "仿宋" },"Arial","Tahoma","Verdana",],},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.5 行高
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({MENU_CONF: {lineHeight: {lineHeightList: ["1", "1.5", "2", "2.5"],},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.6 表情
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");let editorConfig = ref({MENU_CONF: {emotion: {emotions: "😀 😃 😄 😁 😆 😅 😂 🤣 😊 😇 🙂 🙃 😉".split(" "),},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.7 链接
checkLink 校验链接、parseLinkUrl 转换链接 url
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");// 自定义校验链接const customCheckLinkFn = (text, url) => {if (!url) {return;}if (url.indexOf("http") !== 0) {return "链接必须以 http/https 开头";}return true;// 返回值有三种选择:// 1. 返回 true ,说明检查通过,编辑器将正常插入链接// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息};// 自定义转换链接 urlconst customParseLinkUrl = (url) => {if (url.indexOf("http") !== 0) {return `http://${url}`;}return url;};let editorConfig = ref({MENU_CONF: {insertLink: {checkLink: customCheckLinkFn, // 也支持 async 函数parseLinkUrl: customParseLinkUrl, // 也支持 async 函数},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.8 图片
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");// 自定义校验图片const customCheckImageFn = (src, alt, url) => {if (!src) {return;}if (src.indexOf("http") !== 0) {return "图片网址必须以 http/https 开头";}return true;// 返回值有三种选择:// 1. 返回 true ,说明检查通过,编辑器将正常插入图片// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息};// 转换图片链接const customParseImageSrc = (src) => {if (src.indexOf("http") !== 0) {return `http://${src}`;}return src;};let editorConfig = ref({MENU_CONF: {// 插入图片insertImage: {onInsertedImage(imageNode) {if (imageNode == null) return;const { src, alt, url, href } = imageNode;console.log("inserted image", src, alt, url, href);},checkImage: customCheckImageFn, // 也支持 async 函数parseImageSrc: customParseImageSrc, // 也支持 async 函数},// 编辑图片editImage: {onUpdatedImage(imageNode) {if (imageNode == null) return;const { src, alt, url } = imageNode;console.log("updated image", src, alt, url);},checkImage: customCheckImageFn, // 也支持 async 函数parseImageSrc: customParseImageSrc, // 也支持 async 函数},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.9 上传图片
3.9.1 服务端地址
必填,否则上传图片会报错。
let editorConfig = ref({MENU_CONF: {uploadImage: {server: "/api/upload",},},
});
正常情况要求服务端返回体如下,如果不满足可以查看自定义插入。
// 上传成功返回
{"errno": 0, // 注意:值是数字,不能是字符串"data": {"url": "xxx", // 图片 src ,必须"alt": "yyy", // 图片描述文字,非必须"href": "zzz" // 图片的链接,非必须}
}// 上传失败返回
{"errno": 1, // 只要不等于 0 就行"message": "失败信息"
}
3.9.2 基本配置
let editorConfig = ref({MENU_CONF: {uploadImage: {// form-data fieldName ,默认值 'wangeditor-uploaded-image'fieldName: "your-custom-name",// 单个文件的最大体积限制,默认为 2MmaxFileSize: 1 * 1024 * 1024, // 1M// 最多可上传几个文件,默认为 100maxNumberOfFiles: 10,// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []allowedFileTypes: ["image/*"],// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。meta: {token: "xxx",otherKey: "yyy",},// 将 meta 拼接到 url 参数中,默认 falsemetaWithUrl: false,// 自定义增加 http headerheaders: {Accept: "text/x-json",otherKey: "xxx",},// 跨域是否传递 cookie ,默认为 falsewithCredentials: true,// 超时时间,默认为 10 秒timeout: 5 * 1000, // 5 秒},},
});
3.9.3 回调函数
let editorConfig = ref({MENU_CONF: {uploadImage: {// 上传之前触发onBeforeUpload(file) {// file 选中的文件,格式如 { key: file }return file;// 可以 return// 1. return file 或者 new 一个 file ,接下来将上传// 2. return false ,不上传这个 file},// 上传进度的回调函数onProgress(progress) {// progress 是 0-100 的数字console.log("progress", progress);},// 单个文件上传成功之后onSuccess(file, res) {console.log(`${file.name} 上传成功`, res);},// 单个文件上传失败onFailed(file, res) {console.log(`${file.name} 上传失败`, res);},// 上传错误,或者触发 timeout 超时onError(file, err, res) {console.log(`${file.name} 上传出错`, err, res);},},},
});
3.9.4 自定义插入
如果服务端的返回体,不满足所需格式,可以使用 customInsert 自定义插入。
let editorConfig = ref({MENU_CONF: {uploadImage: {customInsert(res, insertFn) {// res 即服务端的返回结果// 从 res 中找到 url alt href ,然后插入图片insertFn(url, alt, href);},},},
});
3.9.5 自定义上传
如果不想使用 wangEditor 自带的上传功能,例如你要上传到阿里云 OSS 。可以通过 customUpload 来自定义上传。
let editorConfig = ref({MENU_CONF: {uploadImage: {async customUpload(file, insertFn) {// file 即选中的文件// 自己实现上传,并得到图片 url alt href// 最后插入图片insertFn(url, alt, href);},},},
});
3.9.6 自定义选择图片
如果不想使用 wangEditor 自带的选择文件功能,例如你有自己的图床,或者图片选择器。可以通过 customBrowseAndUpload 来自己实现选择图片、上传图片,并插入图片。
let editorConfig = ref({MENU_CONF: {uploadImage: {customBrowseAndUpload(insertFn) {// 自己选择文件// 自己上传文件,并得到图片 url alt href// 最后插入图片insertFn(url, alt, href);},},},
});
3.9.7 base64 插入图片
let editorConfig = ref({MENU_CONF: {uploadImage: {// 小于该值就插入 base64 格式(而不上传),默认为 0base64LimitSize: 5 * 1024, // 5kb},},
});
3.10 视频
onInsertedVideo 插入视频之后的回调、checkVideo 校验视频链接、parseVideoSrc 转换视频链接
<script setup lang="ts">import { ref } from "vue";import Rich from "@/components/Rich.vue";let richHtml = ref("");// 自定义校验视频const customCheckVideoFn = (src, poster) => {if (!src) {return;}if (src.indexOf("http") !== 0) {return "视频地址必须以 http/https 开头";}return true;// 返回值有三种选择:// 1. 返回 true ,说明检查通过,编辑器将正常插入视频// 2. 返回一个字符串,说明检查未通过,编辑器会阻止插入。会 alert 出错误信息(即返回的字符串)// 3. 返回 undefined(即没有任何返回),说明检查未通过,编辑器会阻止插入。但不会提示任何信息};// 自定义转换视频const customParseVideoSrc = (src) => {if (src.includes(".bilibili.com")) {// 转换 bilibili url 为 iframe (仅作为示例,不保证代码正确和完整)const arr = location.pathname.split("/");const vid = arr[arr.length - 1];return `<iframe src="//player.bilibili.com/player.html?bvid=${vid}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>`;}return src;};let editorConfig = ref({MENU_CONF: {insertVideo: {onInsertedVideo(videoNode) {if (videoNode == null) return;const { src } = videoNode;console.log("inserted video", src);},checkVideo: customCheckVideoFn, // 也支持 async 函数parseVideoSrc: customParseVideoSrc, // 也支持 async 函数},},});
</script><template><div class="page-rich"><Rich v-model="richHtml" :editorConfig="editorConfig" /></div>
</template>
3.11 上传视频
3.11.1 服务端地址
必填,否则上传图片会报错。
let editorConfig = ref({MENU_CONF: {uploadVideo: {server: "/api/upload",},},
});
正常情况要求服务端返回体如下,如果不满足可以查看自定义插入。
// 上传成功返回
{"errno": 0, // 注意:值是数字,不能是字符串"data": {"url": "xxx", // 视频 src ,必须"poster": "xxx.png" // 视频封面图片 url ,可选}
}// 上传失败返回
{"errno": 1, // 只要不等于 0 就行"message": "失败信息"
}
3.11.2 基本配置
let editorConfig = ref({MENU_CONF: {uploadVideo: {// form-data fieldName ,默认值 'wangeditor-uploaded-video'fieldName: "your-custom-name",// 单个文件的最大体积限制,默认为 10MmaxFileSize: 5 * 1024 * 1024, // 5M// 最多可上传几个文件,默认为 5maxNumberOfFiles: 3,// 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []allowedFileTypes: ["video/*"],// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。meta: {token: "xxx",otherKey: "yyy",},// 将 meta 拼接到 url 参数中,默认 falsemetaWithUrl: false,// 自定义增加 http headerheaders: {Accept: "text/x-json",otherKey: "xxx",},// 跨域是否传递 cookie ,默认为 falsewithCredentials: true,// 超时时间,默认为 30 秒timeout: 15 * 1000, // 15 秒},},
});
3.11.3 回调函数
let editorConfig = ref({MENU_CONF: {uploadVideo: {// 上传之前触发onBeforeUpload(file) {// file 选中的文件,格式如 { key: file }return file;// 可以 return// 1. return file 或者 new 一个 file ,接下来将上传// 2. return false ,不上传这个 file},// 上传进度的回调函数onProgress(progress) {// progress 是 0-100 的数字console.log("progress", progress);},// 单个文件上传成功之后onSuccess(file, res) {console.log(`${file.name} 上传成功`, res);},// 单个文件上传失败onFailed(file, res) {console.log(`${file.name} 上传失败`, res);},// 上传错误,或者触发 timeout 超时onError(file, err, res) {console.log(`${file.name} 上传出错`, err, res);},},},
});
3.11.4 自定义插入
如果服务端的返回体,不满足所需格式,可以使用 customInsert 自定义插入。
let editorConfig = ref({MENU_CONF: {uploadVideo: {customInsert(res, insertFn) {// res 即服务端的返回结果// 从 res 中找到 url poster ,然后插入视频insertFn(url, poster);},},},
});
3.11.5 自定义上传
如果不想使用 wangEditor 自带的上传功能,例如你要上传到阿里云 OSS 。可以通过 customUpload 来自定义上传。
let editorConfig = ref({MENU_CONF: {uploadVideo: {async customUpload(file, insertFn) {// file 即选中的文件// 自己实现上传,并得到视频 url poster// 最后插入视频insertFn(url, poster);},},},
});
3.11.6 自定义选择视频
如果不想使用 wangEditor 自带的选择文件功能,例如你有自己的图床,或者视频文件选择器。可以通过 customBrowseAndUpload 来自己实现选择视频、上传视频,并插入视频
let editorConfig = ref({MENU_CONF: {uploadVideo: {customBrowseAndUpload(insertFn) {// 自己选择文件// 自己上传文件,并得到视频 url poster// 最后插入视频insertFn(url, poster);},},},
});
4. 编辑器 API
4.1 getConfig
获取编辑器所有配置
const handleCreated = (editor) => {const result = editor.getConfig();console.log(result);
};
4.2 getAllMenuKeys
获取编辑器所有 menu 的 key
const handleCreated = (editor) => {const result = editor.getAllMenuKeys();console.log(result);
};
4.3 getMenuConfig
获取单个 menu 的配置。
const handleCreated = (editor) => {const result = editor.getMenuConfig("color");console.log(result);
};
4.4 alert
编辑器 alert ,可通过 customAlert 配置。
editor.alert("错误信息", "error");
customAlert 配置
<script setup lang="ts">import { message } from "antd";const customAlert = (s, t) => {switch (t) {case "success":message.success(s);break;case "info":message.info(s);break;case "warning":message.warning(s);break;case "error":message.error(s);break;default:message.info(s);break;}};
</script><template><div class="editor-content-view"><Toolbar /><Editor @customAlert="customAlert" /></div>
</template>
4.5 handleTab
控制编辑器按 tab 键时,输入什么。
<script setup lang="ts">const handleCreated = (editor: any) => {editor.handleTab = () => editor.insertText("aaaaa");};
</script>
<template><div class="editor-content-view"><Toolbar /><Editor @onCreated="handleCreated" /></div>
</template>
4.6 getHtml
editor.getHtml() 获取非格式化的 html
const result = editor.getHtml();
console.log(result);
4.7 getText
获取当前编辑器的纯文本内容
const handleCreated = (editor) => {const result = editor.getText();console.log(result);
};
4.8 setHtml
重置编辑器的 HTML 内容。
editor.setHtml("<p>hello</p>");
4.9 isEmpty
判断当前编辑器内容是否为空(只有一个空段落)
editor.isEmpty();
4.10 getSelectionText
获取选中的文本
const result = editor.getSelectionText();
console.log(result);
4.11 getElemsByType
通过 type 获取编辑器的 element 列表。
editor.getElemsByType("image"); // 所有图片
editor.getElemsByType("link"); // 所有链接
4.12 getElemsByTypePrefix
通过 type 前缀获取编辑器的 element 列表。
editor.getElemsByTypePrefix("header"); // 获取所有标题 header1 header2 header3...
4.13 deleteBackward
向前删除,相当于按 backspace 键。
editor.deleteBackward();
4.14 deleteForward
向后删除,相当于按 delete 键
editor.deleteForward();
4.15 deleteFragment
删除选中的内容
editor.deleteFragment();
4.16 getFragment
获取选中的内容,json 格式
editor.getFragment();
4.17 insertBreak
在选区回车换行
editor.insertBreak();
4.18 insertText
在选区插入文本
editor.insertText("aaaa");
4.19 dangerouslyInsertHtml
插入富文本
editor.dangerouslyInsertHtml(`<h1>标题</h1><p>文本 <b>加粗</b></p>`);
4.20 clear
清空编辑器内容
editor.clear();
4.21 undo
撤销
editor.undo();
4.22 redo
重做
editor.redo();
4.23 insertNode
在选区插入一个节点
const node = { type: "paragraph", children: [{ text: "simple text" }] };
editor.insertNode(node);
4.24 insertNodes
在选区插入多个节点
import { SlateTransforms } from "@wangeditor/editor";const node1 = { type: "paragraph", children: [{ text: "aaa" }] };
const node2 = { type: "paragraph", children: [{ text: "bbb" }] };
const nodeList = [node1, node2];SlateTransforms.insertNodes(editor, nodeList);
4.25 removeNodes
删除选区所在的节点
import { SlateTransforms } from "@wangeditor/editor";SlateTransforms.removeNodes(editor);
4.26 获取选中节点
可使用 SlateEditor.nodes 获取选中的节点。
import { SlateEditor, SlateElement, SlateNode } from "@wangeditor/editor";const nodeEntries = SlateEditor.nodes(editor, {match: (node) => {if (SlateElement.isElement(node)) {if (node.type === "paragraph") {return true; // 匹配 paragraph}}return false;},universal: true,
});if (nodeEntries == null) {console.log("当前未选中的 paragraph");
} else {for (let nodeEntry of nodeEntries) {const [node, path] = nodeEntry;console.log("选中了 paragraph 节点", node);console.log("节点 path 是", path);}
}
4.27 setNodes
设置选中节点的属性
import { SlateTransforms } from "@wangeditor/editor";SlateTransforms.setNodes(editor,{// @ts-ignoretextAlign: "right",},{mode: "highest", // 针对最高层级的节点}
);
4.28 getParentNode
获取一个节点的父节点
const parentNode = editor.getParentNode(node); // 返回 node 或者 null
4.29 toDOMNode
获取一个节点对应的 DOM 节点
const elem = editor.toDOMNode(node); // 返回 HTMLElement
4.30 isInline
判断一个节点是否是 inline
const inline = editor.isInline(node);
4.31 isVoid
判断一个节点是否是 void
const void = editor.isVoid(node)
4.32 isText
判断一个节点是否是 text
import { SlateText } from "@wangeditor/editor";SlateText.isText(node); // true/false
4.33 isElement
判断一个节点是否是 elem
import { SlateElement } from "@wangeditor/editor";SlateElement.isElement(node); // true/false
4.34 addMark
为选中的文本添加标记(文本样式)
editor.addMark("bold", true); // 加粗
editor.addMark("color", "#999"); // 文本颜色
4.35 removeMark
对选中的文字,取消标记(文本样式)
editor.removeMark("bold"); // 取消加粗
4.36 marks
获取选中文字的标记(文本样式)
import { SlateEditor } from "@wangeditor/editor";SlateEditor.marks(editor); // 例如 { bold: true, color: "#595959" }
4.37 id
获取编辑器 id
editor.id; // 如 'wangEditor-1'
4.38 isFullScreen
编辑器是否全屏
editor.isFullScreen; // true/false
4.39 focus
聚焦到编辑器
editor.focus();// editor.focus(true) // 选区定位到最后
4.40 blur
失焦编辑器
editor.blur();
4.41 isFocused
判断当前编辑器是否聚焦?
editor.isFocused(); // true/false
4.42 updateView
强制更新视图
editor.updateView();
4.43 scrollToElem
滚动到指定元素,类似锚点。
editor.scrollToElem(elemId);
4.44 showProgressBar
显示进度条,一般用于上传功能
editor.showProgressBar(progress); // progress 为 0-100 的数字
4.45 hidePanelOrModal
隐藏当前的弹框 (如插入链接) 和下拉列表(如设置标题、设置字体)
editor.hidePanelOrModal();
4.46 fullScreen
设置为全屏
editor.fullScreen();
4.47 unFullScreen
取消全屏
editor.unFullScreen();
4.48 disable
禁用编辑器,设置为只读
editor.disable();
4.49 isDisabled
判断当前编辑器是否只读?
editor.isDisabled(); // true/false
4.50 enable
取消禁用,取消只读
editor.enable();
4.51 destroy
销毁编辑器和工具栏
editor.destroy();
4.52 getEditableContainer
获取编辑区域容器 DOM 节点
editor.getEditableContainer();
4.53 selection
获取编辑器当前的选区。如果未选中,则返回 null 。
editor.selection; // selection 或 null
selection 数据结构如下:
{"anchor": { "path": [1, 0], "offset": 8 },"focus": { "path": [1, 0], "offset": 10 }
}
4.54 select
选中一个指定的选区。
const newSelection = {anchor: { path: [1, 0], offset: 8 },focus: { path: [1, 0], offset: 10 },
};
editor.select(newSelection);
4.55 selectAll
选中所有内容
editor.selectAll();
4.56 deselect
取消选中
editor.deselect();
4.57 move
移动光标
editor.move(3); // 移动 3 个字符
4.58 moveReverse
反向移动光标
editor.moveReverse(2); // 反向移动 2 个字符
4.59 restoreSelection
恢复最近一次非 null 选区。如编辑器 blur 之后,再重新恢复选区。
editor.restoreSelection();
4.60 isSelectedAll
判断编辑器是否全部选中。
editor.isSelectedAll(); // true/false
4.61 getSelectionPosition
获取选区的定位,将视情况返回 left right top bottom 的其中几个。
editor.getSelectionPosition(); // 例如 { left: "80.15px", top: "116px" }
4.62 getNodePosition
获取某个节点的定位,将视情况返回 left right top bottom 的其中几个。
editor.getNodePosition(node); // 例如 { left: "80.15px", top: "116px" }
4.63 on
监听某个事件
editor.on("event-key", fn);
4.64 off
取消监听
editor.off("event-key", fn);
4.65 once
只监听一次
editor.once("event-key", fn);
4.66 emit
触发事件
editor.emit("event-key");
4.67 内置的事件
editor.on("fullScreen", () => {console.log("fullScreen");
});
editor.on("unFullScreen", () => {console.log("unFullScreen");
});
editor.on("scroll", () => {console.log("scroll");
});
editor.on("modalOrPanelShow", (modalOrPanel) => {console.log(modalOrPanel);
});
editor.on("modalOrPanelHide", () => {console.log("modalOrPanelHide");
});
相关文章:

wangEditor 富文本详解
前言:wangEditor 官网 。本文档讲解 wangEditor 在 vue3 中的使用。 一:快速开始 1. 安装 需要安装 wangeditor/editor、wangeditor/editor-for-vuenext 两个依赖 # 安装 editor npm install wangeditor/editor # or yarn add wangeditor/editor # o…...

文献速递:深度学习医学影像心脏疾病检测与诊断--从SPECT/CT衰减图中深度学习冠状动脉钙化评分提高了对重大不良心脏事件的预测
Title 题目 Deep Learning Coronary Artery Calcium Scores from SPECT/CT Attenuation Maps Improve Prediction of Major Adverse Cardiac Events 从SPECT/CT衰减图中深度学习冠状动脉钙化评分提高了对重大不良心脏事件的预测 01 文献速递介绍 低剂量非门控CT衰减校正&am…...

Java多线程:常见的线程的创建方法及Thread类详解
目录 一.并发编程相关概念 线程与进程 多线程 Java中线程的状态 二.线程的创建方法 方法一:继承Thread类 方法二:实现Runnable接口 其他方法 三.Thread类详解 Thread常见构造方法 Thread常见属性 Thread常见方法 start() 与 run() sleep(…...

一招搞定生产管理
劳动力成本上升,原材料价格上涨,企业生产成本逐年增加,市场竞争越来越激烈,传统的中小制造企业面临着巨大的挑战。 企业的数字化转型如今成为炙手可热的高频词语,越来越多的中小制造企业已经开始上云,实践SaaS模式的生产管理系统…...

学习CSS3,实现红色心形loading特效
试想一下,如果你的网站在加载过程中,loading图由一个老旧的菊花转动图片,变为一个红色的心形loading特效,那该有多炫酷啊。 目录 实现思路 初始化HTML部分 延迟动画是重点 设定动画效果 完整源代码 最后 实现思路 每个…...

深度学习之基于Matlab神经网络的活体人脸和视频人脸识别系统
欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 人脸识别技术作为生物识别技术的一种,近年来得到了广泛的关注和应用。与传统的身份认证方…...

充电桩测试:负载箱的重要性
随着电动汽车的普及,充电桩的需求也在不断增加。为了保证充电桩的安全、稳定和高效运行,对其进行严格的测试是必不可少的。在充电桩测试过程中,负载箱作为一种重要的测试设备,对于评估充电桩的性能和可靠性具有重要意义。 负载箱可…...

贪心算法、Dijkstra和A*类路径搜索算法
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言系列文章目录前言1.贪心算法、Dijkstra和A*类路径搜索算法(1)greedy best frist search贪心算法(仅仅考虑启发式代价)1.核心思想2.构造启发式猜…...

Debian是什么?有哪些常用命令
目录 一、Debian是什么? 二、Debian常用命令 三、Debian和CentOS的区别 四、Debian和CentOS的优缺点 五、Debian和CentOS的运用场景 一、Debian是什么? Debian是一种流行的开源Linux操作系统。 Debian是一个以Linux内核为基础的操…...

万兴PDF专家 PDFelement Pro v10.3.8 破姐版!
🧑💻万兴PDF专家 PDFelement Pro v10.3.8 破姐版 (https://docs.qq.com/sheet/DRVVxTHJ3RXJFVHVr)...

Ubuntu22.04 私钥登录
1. 背景 以前一直使用秘钥登录Linux,最近新装了一台Ubuntu 22.04,照旧部署公钥,使用私钥登录,结果SecureCRT 登录没有问题,使用Xshell登录一直报“所选的用户密钥未在远程主机上注册,请再试一次”。然后各种试&#x…...

Java_JVM_JVMs
JVM 官方文档说明文档目录 官方文档 JVM Specification 说明 以Java SE 17为标准 文档目录 2:JVM 结构 class文件数据类型 基本数据类型引用数据类型 运行时数据区 栈帧 其他内容 对象的表示浮点数运算特殊方法 初始化方法【实例、类】多态方法 3ÿ…...

Linux系统编程之基本指令
零、Linux发展史 1、诞生 1991年10月5日,赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组 (comp.os.minix)中宣布他编制出了一种类似UNIX的小操作系统,叫Linux。新的操作系统是受到另一个UNIX的小操作系统—…...

[1702]java旅游资源网上填报系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java旅游资源网上填报系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql…...

【Flask 系统教程 3】请求与响应
Flask 是一个灵活而强大的 Web 框架,而请求与响应则是构建 Web 应用的核心组成部分。在本文中,我们将探讨 Flask 中请求与响应的各种用法,包括不同的请求方法、重定向、响应对象、获取查询参数以及文件上传等。 请求 在 Flask 中࿰…...

jsp校园商城派送系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 校园商城派送系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统采用serlvetdaobean mvc 模式,系统主要采用B/S模式 开发。开发环境为TOMCAT7.0,Myeclipse8.…...

【Linux】System V 共享内存
文章目录 1. 共享内存示意图2. 共享内存数据结构3. 共享内存函数shmgetshmatshmdtshmctl 4. 实例代码测试共享内存5. 共享内存相关命令6. System V 消息队列(了解)7. System V 信号量(了解) 共享内存区是最快的 IPC 形式。一旦这样…...

拼多多标准推广怎么玩
拼多多标准推广的玩法主要包括以下方面: 拼多多推广可以使用3an推客。3an推客(CPS模式)给商家提供的营销工具,由商家自主设置佣金比例,激励推广者去帮助商家推广商品链接,按最终有效交易金额支付佣金&…...

HFSS学习-day2-T形波导的优化设计
入门实例–T形波导的内场分析和优化设计 HFSS--此实例优化设计 优化设计要求1. 定义输出变量Power31、Power21、和Power11,表示Port3、Port2、Port1的输出功率2.参数扫描分析添加扫描变量和输出变量进行一个小设置添加输出变量进行扫描分析 3. 优化设计,…...

贪吃蛇小游戏(c语言)
1.效果展示 屏幕录制 2024-04-28 205129 2.基本功能 • 贪吃蛇地图绘制 • 蛇吃食物的功能 (上、下、左、右方键控制蛇的动作) • 蛇撞墙死亡 • 蛇撞自身死亡 • 计算得分 • 蛇身加速、减速 • 暂停游戏 3.技术要点 C语言函数、枚举、结构…...

多商户Docker Supervisor进程管理器部署
Dockerfile 根目录下没有Dockerfile的可以复制下面的命令 # 使用基础镜像 FROM leekay0218/crmeb-mer## 复制代码 ## 在本地调试注释掉,使用映射把文件映射进去 #ADD ./ /var/www# 设置工作目录 WORKDIR /var/www# 设置时区为上海 ENV TZAsia/Shanghai RUN ln -sn…...

Vue--》从零开始打造交互体验一流的电商平台(一)
今天开始使用 vue3 ts 搭建一个电商项目平台,因为文章会将项目的每处代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的github上,大家可以自行去进行下载运行,希…...

uniapp 自定义相机插件(组件版、缩放、裁剪)组件 Ba-CameraView
自定义相机插件(组件版、缩放、裁剪) Ba-CameraView 简介(下载地址) Ba-CameraView 是一款自定义相机拍照组件,支持任意界面,支持裁剪 支持任意自定义界面支持手势缩放支持裁剪(手势拖动、比…...

如何在Python中生成随机密码?
你可以使用Python的random模块来生成随机密码。下面是一个生成随机密码的简单示例代码: import random import stringdef generate_random_password(length):characters string.ascii_letters string.digits string.punctuationpassword .join(random.choice(c…...

【Git管理工具】使用Docker+浪浪云服务器部署GitLab服务器
一、什么是GitLab 1.1.GitLab简介 GitLab 是一个开源的 DevOps 平台,它基于 Git 版本控制系统提供了从项目规划、源代码管理到持续集成、持续部署、监控和安全的完整生命周期管理。GitLab 是一个为开发者提供协作工作的工具,它使得团队能够高效地在同一…...

速盾:什么是cdn架构
CDN(Content Delivery Network)即内容分发网络,是一种分布式的架构,用于提高互联网上的内容传输速度和用户体验。CDN架构通过将内容分发到全球多个节点,使用户能够从最近的节点获取内容,从而减少延迟和网络…...

spring高级篇(十)
1、内嵌tomcat boot框架是默认内嵌tomcat的,不需要手动安装和配置外部的 Servlet 容器。 简单的介绍一下tomcat服务器的构成: Catalina: Catalina 是 Tomcat 的核心组件,负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包…...

map、set底层封装模拟实现(红黑树)
文章目录 一、红黑树1.1红黑树的规则:1.2红黑树的插入操作1.2.1不需要旋转(如果叔叔存在且为红,这里的C表示孩子,P表示父亲,U表示叔叔,G表示祖父),包含四种情况,无论孩子在哪里&…...

PHP8.2-xlswriter 扩展
https://pecl.php.net/package/xlswriter ### 进入/root/ cd ~ ### 下载扩展 wget https://pecl.php.net/get/xlswriter-1.5.5.tgz ### 解压扩展 tar -zxvf xlswriter-1.5.5.tgz ### 进入扩展目录 cd xlswriter-1.5.5 ### 查找对应php版本的phpize find / -name phpi…...

imx6ull开发板设置SD卡启动,SD卡中烧写uboot,kernel,设备树,根文件系统fs
IMX6ULL ARM Linux开发板SD卡启动,SD卡的分区与分区格式化创建_sd制作分区-CSDN博客...