1. npm install --save @wangeditor/editor-for-vue
2. npm install js-base64
3.npm install @wangeditor/editor
<template>
<div>
<Toolbar
:editor="editor"
:defaultConfig="toolbarConfig"
:mode="mode"
/>
<Editor
v-model="editors"
:defaultConfig="editorConfig"
:mode="mode"
style="height: 400px"
@onCreated="onCreated"
/>
<button @click="submit">点击提交</button>
<button @click="show">展示功能</button>
<div class="show">
<Editor
v-model="editors"
:defaultConfig="editorConfig"
:mode="mode"
style="height: 400px"
@onCreated="onCreated"
/>
<div v-html="content"></div>
</div>
</div>
</template>
<script>
import { Base64 } from 'js-base64'
import { Loading, Message } from 'element-ui'
import { DomEditor } from "@wangeditor/editor";
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
export default {
components: { Editor, Toolbar },
data() {
let loading = ''
return {
editor: null,
editors:'',
content: "",
toolbarConfig: {
toolbarKeys: [
// 一些常用的菜单 key
"headerSelect", // 标题
// "header1", // 标题1
// "header2", // 标题2
// "header3", // 标题3
// "header4", // 标题4
// "header5", // 标题5
"bold", // 粗体
"underline", // 下划线
"italic", // 斜体
"through", // 删除线
"code", // 行内代码
"sub", // 下标
"sup", // 上标
"clearStyle", // 清除格式
"color", // 字体颜色
"bgColor", // 背景色
"fontSize", // 字号
"fontFamily", // 字体
"indent", // 增加缩进
"delIndent", // 减少缩进
"justifyLeft", // 左对齐
"justifyRight", // 右对齐
"justifyCenter", // 居中对齐
"justifyJustify", // 两端对齐
"lineHeight", // 行高
// "insertImage", // 网络图片
"deleteImage", // 删除图片
"editImage", // 编辑图片
"viewImageLink", // 查看链接
"imageWidth30", // 图片宽度相对于编辑器宽度的百分比30
"imageWidth50", // 图片宽度相对于编辑器宽度的百分比50
"imageWidth100", // 图片宽度相对于编辑器宽度的百分比100
"divider", // 分割线
"emotion", // 表情
"insertLink", // 插入链接
"editLink", // 修改链接
"unLink", // 取消链接
"viewLink", // 查看链接
// "codeBlock", // 代码块
// "blockquote", // 引用
"todo", // 待办
"redo", // 重做
"undo", // 撤销
"fullScreen", // 全屏
"enter", // 回车
"bulletedList", // 无序列表
"numberedList", // 有序列表
"insertTable", // 插入表格
"deleteTable", // 删除表格
"insertTableRow", // 插入行
"deleteTableRow", // 删除行
"insertTableCol", // 插入列
"deleteTableCol", // 删除列
"tableHeader", // 表头
"tableFullWidth", // 宽度自适应
// "insertVideo", // 插入网络视频
// "uploadVideo", // 上传视频
// "editVideoSize", // 修改视频尺寸
"uploadImage", // 上传图片
// "codeSelectLang" // 选择语言
// 对齐
// {
// iconSvg:
// '<svg viewBox="0 0 1024 1024"><path d="M768 793.6v102.4H51.2v-102.4h716.8z m204.8-230.4v102.4H51.2v-102.4h921.6z m-204.8-230.4v102.4H51.2v-102.4h716.8zM972.8 102.4v102.4H51.2V102.4h921.6z"></path></svg>',
// key: "group-justify",
// menuKeys: [
// "justifyLeft",
// "justifyRight",
// "justifyCenter",
// "justifyJustify",
// ],
// title: "对齐",
// },
]
},
editorConfig: {
placeholder: '请输入内容...' ,
MENU_CONF: {
uploadImage: {
server: '/api/blade-resource/oss/endpoint/put-file',
fieldName: 'file',
// 单个文件的最大体积限制,默认为 2M
maximgSize: 10 * 1024 * 1024, // 10M
// 最多可上传几个文件,默认为 100
maxNumberOfimgs: 10,
// 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
allowedimgTypes: ['image/*'],
// 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。
meta: {
// token: 'xxx',
// otherKey: 'yyy'
// img:''
},
// 将 meta 拼接到 url 参数中,默认 false
metaWithUrl: false,
// 自定义增加 http header
headers: {
Accept: 'text/x-json',
// [website.tokenHeader]: `bearer ${getToken()}`,
// Authorization: `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`
},
// 跨域是否传递 cookie ,默认为 false
withCredentials: true,
// 超时时间,默认为 10 秒
timeout: 10 * 1000, //10 秒
// 上传前
onBeforeUpload(imgs) {
loading = Loading.service({
lock: true,
text: '图片正在上传中,请耐心等待',
spinner: "el-icon-loading"
});
return imgs;
},
// 自定义插入图片
customInsert(res, insertFn) {
console.log('customInsert', res)
// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理
// 先关闭等待的ElMessage
loading.close();
if (res.code === 200) {
Message({
message: '图片上传成功',
type: 'success'
})
} else {
Message({
message: '图片上传失败,请重新尝试',
type: 'error'
})
}
//获取文本中的img
// var reg = /(?<=img src=").*?(?=" alt=)/g;
// //this.formLabelAlign.content是文本内容
// let addresslist=this.formLabelAlign.content.match(reg);
// 从 res 中找到 url alt href ,然后插入图片
let imgUrL = 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
function urlToBase64(url) {
return new Promise((resolve, reject) => {
let image = new Image();
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
// 将图片插入画布并开始绘制
canvas.getContext("2d").drawImage(image, 0, 0);
// result
let result = canvas.toDataURL("image/png");
resolve(result);
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin", "Anonymous");
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error("urlToBase64 error"));
};
});
}
urlToBase64(imgUrL).then((res) => {
// 转化后的base64图片地址
// console.log("base64", res);
insertFn(res);
});
},
// 单个文件上传成功之后
onSuccess(img, res) {
console.log(`${img.name} 上传成功`, res);
},
// 单个文件上传失败
onFailed(img, res) {
console.log(`${img.name} 上传失败`, res);
},
// 上传进度的回调函数
onProgress(progress) {
console.log('progress', progress);
// progress 是 0-100 的数字
},
// 上传错误,或者触发 timeout 超时
onError(img, err, res) {
console.log(`${img.name} 上传出错`, err, res);
}
}
}
},
mode: 'default', // or 'simple'
}
},
methods:{
submit() {
console.log("富文本提交内容");
console.log(this.editor.getHtml());
this.content = this.editor.getHtml();
},
show() {
const toolbar = DomEditor.getToolbar(this.editor);
const curToolbarConfig = toolbar.getConfig();
console.log(curToolbarConfig.toolbarKeys);
},
onCreated(editor) {
this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
},
beforeDestroy() {
const editor = this.editor
if (editor == null) return
editor.destroy() // 组件销毁时,及时销毁编辑器
}
}
}
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style lang="scss" scoped>
::v-deep h5, .h5 {
font-size: 14px;
}
::v-deep h4, .h4 {
font-size: 16px;
font-weight: bold;
}
::v-deep h3, .h3 {
font-size: 18px;
font-weight: bold;
}
::v-deep h2, .h2 {
font-size: 20px;
font-weight: bold;
}
::v-deep h1, .h1 {
font-size: 22px;
font-weight: bold;
}
::v-deep i {
font-style: italic
}
::v-deep .w-e-toolbar .w-e-menu i {
font-style: normal;
}
::v-deep ol {
list-style-type: decimal;
}
::v-deep ol{
margin: 10px 0 10px 22px;
list-style-type: decimal;
}
::v-deep ul{
margin: 10px 0 10px 22px;
list-style-type: disc;
}
/* table 样式 */
::v-deep table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
::v-deep table td,
::v-deep table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
//padding: 3px 5px;
width: 32px;
height:32px;
}
::v-deep table th {
border-bottom: 2px solid #ccc;
text-align: center;
background-color: #f1f1f1 ;
}
/* blockquote 样式 */
::v-deep blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
min-height: 24px;
font-size: 100%;
background-color: #f1f1f1;
}
/* code 样式 */
::v-deep code {
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
::v-deep pre code {
display: block;
}
::v-deep a {
// text-decoration: underline;
color: #5592e5;
}
//::v-deep .w-e-bar-item button {
// .title{
// background: #fff;
// margin-top: 10px;
// }
//}
</style>