现有的Quill比较简单,无法满足业务需求(例如SEO的图片属性编辑需求)
Quill已经有比较长的时间没有更新了,虽然很灵活,但是官方demo都没有一个。
业务前期也没有这块的需求,也没有考虑到这块的扩展问题。
市面上常见的富文本编辑器比较:
官网地址
直接找到对应的Vue版本就可以了,React有用到的话,也可以用下(本人没有用到)
官方提供了一个在线的版本,可以直接在线编辑试用。如果网络不好,也可以把代码下载到本地处理。
Demo代码在线运行地址
npm install @wangeditor/editor --save # 或者 yarn add @wangeditor/editor
npm install @wangeditor/editor-for-vue --save # 或者 yarn add @wangeditor/editor-for-vue
注:1、安装前请注意看下你对应的Vue版本是Vue2还是Vue3。
2、可能会常出现版本冲突的问题,如果出现版本的问题,请添加npm的安装参数 --legacy-peer-deps(具体干啥用的,请自行百度)
(1) 组件引用
<template>
<div>
<div style="border: 1px solid #ccc; margin-top: 10px">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
div>
div>
template>
(2)默认配置项
<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css";
export default {
name: "MyEditor",
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: "hello world
",
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
},
editorConfig: {
placeholder: "请输入内容...",
// autoFocus: false,
// 所有的菜单配置,都要在 MENU_CONF 属性下
MENU_CONF: {},
},
};
},
methods: {
onCreated(editor) {
// 【注意】一定要用 Object.seal() 否则会报错
this.editor = Object.seal(editor);
}
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
this.html = "Ajax 异步设置内容 HTML
";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!!
},
};
</script>
框框出来了,你发现上传图片会提示下面错误:
原因是需要配置上传路径地址。
根据官方的说法,直接配置对应的参数即可
editorConfig: {
//菜单配置
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须要配置正确
server: '/api/upload',
...
}
}
}
请查看菜单配置
个人菜单配置内容
editorConfig: {
placeholder: "请输入内容...",
pasteFilterStyle: false,
zIndex: 12000,
//看这里
//-----------------------------------
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须配置
server: process.env.VUE_APP_API_BASE_URL + "/api/upload",
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: [],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
fieldName: "file",
meta: {
//官网中把token放到了这里,但是请求的时候会看不到token
},
headers: {
//token放这里 getUserToken()这个方法需要自己实现
Authorization: "Bearer " + getUserToken(),
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 跨域是否传递 cookie ,默认为 false
withCredentials: false,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
customInsert(res, insertFn) {
// 从 res 中找到 url alt href ,然后插图图片
// res 是上传后,从后端返回的结果集。具体根据返回对象进行设置。
if(res.code===200){
const imageObj=res.data[0]
insertFn(imageObj.url, imageObj.name, imageObj.url)
}
},
},
},
mode:"default",// "simple",
}
编辑器配置
工具栏配置
有的时候需要清除历史数据,这样处理的话主要是方便进行重新赋值。
Clear()方法进行重置
(1)添加边框
样式调整写的稍微有点模糊,需要自己慢慢定位下。
最外层的样式如下:
style="border: 1px solid #1890ff"
最外层包括Toolbar和Editor两个组件。
(2)图片编辑框调整
图片的样式默认是没有高亮,如果需要高亮,需要对现在的样式进行调整。
代码如下:
.editor >>> .w-e-text-container{
.w-e-hover-bar{
/* 选中图片样式样式覆盖*/
border: 1px solid #1890ff;
color: #1890ff;
}
.w-e-modal {
/* 弹框边框样式覆盖 */
border: 1px solid #1890ff;
}
.w-e-modal button {
/* 弹框按钮样式覆盖 */
background-color: #1890ff;
color: #fff;
}
}
全部代码如下:
<template>
<div>
<div style="border: 1px solid #ccc; margin-top: 10px">
<Toolbar
style="border-bottom: 1px solid #ccc"
:editor="editor"
:defaultConfig="toolbarConfig"
/>
<Editor
style="height: 400px; overflow-y: hidden"
:defaultConfig="editorConfig"
v-model="html"
@onChange="onChange"
@onCreated="onCreated"
/>
div>
div>
template>
<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
export default {
name: "MyEditor",
components: { Editor, Toolbar },
data() {
return {
editor: null,
html: "hello world
",
toolbarConfig: {
// toolbarKeys: [ /* 显示哪些菜单,如何排序、分组 */ ],
// excludeKeys: [ /* 隐藏哪些菜单 */ ],
},
editorConfig: {
place
holder: "请输入内容...",
pasteFilterStyle: false,
zIndex: 12000,
//看这里
//-----------------------------------
MENU_CONF: {
// 配置上传图片
uploadImage: {
//server必须配置
server: process.env.VUE_APP_API_BASE_URL + "/api/upload",
// 最多可上传几个文件,默认为 100
maxNumberOfFiles: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedFileTypes: [],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
fieldName: "file",
meta: {
//官网中把token放到了这里,但是请求的时候会看不到token
},
headers: {
//token放这里 getUserToken()这个方法需要自己实现
Authorization: "Bearer " + getUserToken(),
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 跨域是否传递 cookie ,默认为 false
withCredentials: false,
// 超时时间,默认为 10 秒
timeout: 5 * 1000, // 5 秒
customInsert(res, insertFn) {
// 从 res 中找到 url alt href ,然后插图图片
// res 是上传后,从后端返回的结果集。具体根据返回对象进行设置。
if(res.code===200){
const imageObj=res.data[0]
insertFn(imageObj.url, imageObj.name, imageObj.url)
}
},
},
},
mode:"default",// "simple",
}
};
},
methods: {
onCreated(editor) {
this.editor = Object.seal(editor); // 【注意】一定要用 Object.seal() 否则会报错
},
},
mounted() {
// 模拟 ajax 请求,异步渲染编辑器
setTimeout(() => {
this.html = "Ajax 异步设置内容 HTML
";
}, 1500);
},
beforeDestroy() {
const editor = this.editor;
if (editor == null) return;
editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!!
},
};
script>
(1)整体来讲比较简单
(2)需要注意是个性化方面的设置
①个性化,官方有说明,但是示例不太明显。需要自己一个个尝试
有点小bug(还能忍受下)。
图片太大会直接选中图片导致属性框不显示的问题
ps:editor.destroy(); // 组件销毁时,及时销毁 editor ,重要!!! 这个在弹窗的时候,最好销毁所有的子组件。这样处理的话不会导致点开多次不回显的问题。