如图
1、下载依赖
2、elm引入(可省略)
main.js 或者 按需引入
3、cv
<template><div style="background: #f1f3f4"><div style="width: 100%; height: 42px"><!-- 工具栏 --><Toolbarid="tool-container"style="width: 100%;background: #ffffff;border-bottom: 1px solid #e8e8e8;position: fixed;top: 0;z-index: 999;border-top: 1px solid #e5e5ea;":editor="editor":defaultConfig="toolbarConfig":mode="mode"/></div><!-- 包裹盒子 --><div style="width: 100%"><!-- 最大盒子 --><div style="width: 100%; background: #f1f3f4; border-radius: 0px"><div style="height: 10px"></div><!-- 编辑器 --><divstyle="overflow-y: hidden;width: 768px;margin: 0 auto;background-color: #fff;border: 1px solid #e8e8e8;box-shadow: 0 2px 10px rgb(0 0 0 / 12%);padding: 48px 72px;"><!-- 标题栏 --><divstyle="height: 54px;margin: 0 10px;border-bottom: 1px solid #e8e8e8;"><el-inputtype="text"placeholder="请输入文章标题(1~24个字)"v-model="chapterTitle"maxlength="24"show-word-limit></el-input></div><!-- 编辑栏 --><Editorid="editor-container"style="min-height: 800px;width: 100%;text-align: justify;border-bottom: 1px solid #e8e8e8;"v-model="chapterContent":defaultConfig="editorConfig":defaultContent="jsonContent":mode="mode"@onCreated="onCreated"></Editor><div style="height: 40px; line-height: 40px; text-align: end">Lv Jj</div><!-- 进度条 --><el-progressv-show="showProgress"color="#ff570f":text-inside="true":stroke-width="15":percentage="progress"></el-progress></div><div style="height: 50px"></div></div></div></div>
</template><script>
import Vue from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
// import { getOss } from "@/api/upload.js";export default Vue.extend({data() {let that = this;return {progress: 0, // 进度条数据showProgress: false, //进度条的显示url: "",chapterTitle: "", // 章节标题chapterContent: "", // 章节内容 编辑器初始化内容的位置// editor配置开始 -------------------------------------------------editor: null,toolbarConfig: {// 工具栏配置toolbarKeys: [// 撤销栏"undo","redo","|",// 正文栏"fontSize","bold",{key: "group-list",title: "列表",iconSvg:'<svg t="1670983367428" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6698" width="200" height="200"><path d="M187.392 70.656q28.672 0 48.64 19.456t19.968 48.128l0 52.224q0 28.672-19.968 48.64t-48.64 19.968l-54.272 0q-27.648 0-47.616-19.968t-19.968-48.64l0-52.224q0-28.672 19.968-48.128t47.616-19.456l54.272 0zM889.856 70.656q27.648 0 47.616 19.456t19.968 48.128l0 52.224q0 28.672-19.968 48.64t-47.616 19.968l-437.248 0q-28.672 0-48.64-19.968t-19.968-48.64l0-52.224q0-28.672 19.968-48.128t48.64-19.456l437.248 0zM187.392 389.12q28.672 0 48.64 19.968t19.968 48.64l0 52.224q0 27.648-19.968 47.616t-48.64 19.968l-54.272 0q-27.648 0-47.616-19.968t-19.968-47.616l0-52.224q0-28.672 19.968-48.64t47.616-19.968l54.272 0zM889.856 389.12q27.648 0 47.616 19.968t19.968 48.64l0 52.224q0 27.648-19.968 47.616t-47.616 19.968l-437.248 0q-28.672 0-48.64-19.968t-19.968-47.616l0-52.224q0-28.672 19.968-48.64t48.64-19.968l437.248 0zM187.392 708.608q28.672 0 48.64 19.968t19.968 47.616l0 52.224q0 28.672-19.968 48.64t-48.64 19.968l-54.272 0q-27.648 0-47.616-19.968t-19.968-48.64l0-52.224q0-27.648 19.968-47.616t47.616-19.968l54.272 0zM889.856 708.608q27.648 0 47.616 19.968t19.968 47.616l0 52.224q0 28.672-19.968 48.64t-47.616 19.968l-437.248 0q-28.672 0-48.64-19.968t-19.968-48.64l0-52.224q0-27.648 19.968-47.616t48.64-19.968l437.248 0z" p-id="6699"></path></svg>',menuKeys: ["bulletedList", "numberedList"],},"divider","blockquote",{key: "group-justify",title: "对齐",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>',menuKeys: ["justifyLeft","justifyCenter","justifyRight","justifyJustify",],},"todo",{key: "group-more-style", // 必填,要以 group 开头title: "...", // 必填iconSvg:'<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>', // 可选menuKeys: ["italic","through","underline","sup","sub","indent","delIndent",// 'codeBlock',// 'code',"clearStyle","lineHeight",], // 下级菜单 key ,必填},"|",// 颜色栏"bgColor","color","|",{key: "group-image",title: "图片",iconSvg:'<svg viewBox="0 0 1024 1024"><path d="M959.877 128l0.123 0.123v767.775l-0.123 0.122H64.102l-0.122-0.122V128.123l0.122-0.123h895.775zM960 64H64C28.795 64 0 92.795 0 128v768c0 35.205 28.795 64 64 64h896c35.205 0 64-28.795 64-64V128c0-35.205-28.795-64-64-64zM832 288.01c0 53.023-42.988 96.01-96.01 96.01s-96.01-42.987-96.01-96.01S682.967 192 735.99 192 832 234.988 832 288.01zM896 832H128V704l224.01-384 256 320h64l224.01-192z"></path></svg>',menuKeys: ["insertImage", "uploadImage"],// menuKeys: ['insertImage']},{key: "group-video",title: "视频",iconSvg:'<svg viewBox="0 0 1024 1024"><path d="M981.184 160.096C837.568 139.456 678.848 128 512 128S186.432 139.456 42.816 160.096C15.296 267.808 0 386.848 0 512s15.264 244.16 42.816 351.904C186.464 884.544 345.152 896 512 896s325.568-11.456 469.184-32.096C1008.704 756.192 1024 637.152 1024 512s-15.264-244.16-42.816-351.904zM384 704V320l320 192-320 192z"></path></svg>',menuKeys: ["insertVideo", "uploadVideo"],// menuKeys: ['insertVideo']},"insertLink","emotion","insertTable","|",],// 135编辑器的位置// insertKeys: {// index: 21, // 插入的位置,基于当前的 toolbarKeys// keys: ['codeSelectLang']// }},// 菜单配置editorConfig: {placeholder: "输入正文",hoverbarKeys: {text: {menuKeys: ["fontSize","insertLink","bulletedList","|","bold","through","color","bgColor","clearStyle",],},image: {menuKeys: ["imageWidth100", "deleteImage"],},video: {menuKeys: [],},},MENU_CONF: {// 配置字号fontSize: {fontSizeList: [{ name: "H1", value: "20px" },{ name: "H2", value: "19px" },{ name: "H3", value: "18px" },{ name: "正文", value: "17px" },],},lineHeight: {lineHeightList: ["1", "1.5", "1.6", "1.75", "2", "3"],},// 配置上传图片uploadImage: {//上传图片async customUpload(file, insertFn) {// file 即选中的文件// 自己实现上传,并得到图片 url alt href// 最后插入图片console.log(file);// 判断文件格式是否符合要求规范if (!/\.(bmp|tiff|gif|png|jpeg|jpg)$/.test(file.name)) {alert("图片类型必须是,bmp/tiff/gif/png/jpeg/jpg中的一种");return false;}that.getClient().then(function (client) {client.put("zsdl/image/" + new Date().getTime(), file).then(function (res) {that.$message.success("上传图片成功");// 上传图片,返回地址console.log(res, "res-----");console.log("上传图片sucess:" + res.url);// 回显图片insertFn(res.url);}).catch(function (err) {// console.log('上传失败')that.$message.error(err);// console.log(err)});}).catch(function (error) {that.$message.error(error.message);// console.log('失败' + error.message)});},maxFileSize: 10 * 1024 * 1024, // 10M 图片大小限制fieldName: "file", //上传类型allowedFileTypes: ["bmp/*","tiff/*","gif/*","png/*","jpeg/*","jpg",], // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []// 自定义上传参数,传递图片时需要带一些参数过去写在这。参数会被添加到 formData 中,一起上传到服务端。meta: {// token: 'xxx',// otherKey: 'yyy'// file:''},// 将 meta 拼接到 url 参数中,默认 falsemetaWithUrl: false,// 自定义设置请求头,比如添加token之类的headers: {// Accept: 'text/x-json',// otherKey: 'xxx'},// 跨域是否传递 cookie ,默认为 falsewithCredentials: true,// 超时时间,默认为 10 秒timeout: 10 * 1000,// 上传进度的回调函数,可以用来显示进度条onProgress(progress) {// progress 是 0-100 的数字console.log("progress", progress);},// 自定义插入图片customInsert(res, insertFn) {// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理// 先关闭等待的Messagethis.Message.closeAll();if (res.code === 200) {this.Message.success({message: `${res.data.originalName} 上传成功`,});} else {this.Message.error({message: `${res.data.originalName} 上传失败,请重新尝试`,});}insertFn(res.data.link, res.data.name, res.data.link);},// 单个文件上传成功之后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);},},// 配置上传视频uploadVideo: {//上传视频async customUpload(file, insertFn) {// file 即选中的文件// 自己实现上传,并得到图片 url alt href// 最后插入图片console.log(file);// 判断文件格式是否符合要求规范if (!/\.(mpeg|avi|navi|asf|wmv|mov|3gp|mp4|m4v|vob)$/.test(file.name)) {alert("视频类型必须是,mpeg/avi/navi/asf/wmv/mov/3gp/mp4/m4v/vob中的一种");return false;}that.getClient().then(function (client) {client.multipartUpload("zsdl/video/" + new Date().getTime(),file,{progress(p) {console.log(p, "进度-----");that.showProgress = true;if (p == 1) {setTimeout(() => {that.$message.success("上传成功");that.showProgress = false;}, 3000);}that.progress = Number((p * 100).toFixed(0));that.progress =that.progress > 100 ? 100 : that.progress;},})// .put('zsdl/video/' + new Date().getTime(), file).then(function (res) {that.$message.success("上传视频成功");// 上传视频,返回地址console.log(res, "res-----");// that.videoAddress = res.res.requestUrls[0].split('?')[0] //这个也很重要,必须切割,要不链接显示错误console.log("上传视频sucess:" +res.res.requestUrls[0].split("?")[0]);// 回显视频insertFn(res.res.requestUrls[0].split("?")[0]);}).catch(function (err) {// console.log('上传失败')that.$message.error(err);// console.log(err)});}).catch(function (error) {that.$message.error(error.message);// console.log('失败' + error.message)});},// 单个文件的最大体积限制,默认为 10MmaxFileSize: 50 * 1024 * 1024, // 50MfieldName: "your-custom-name", //上传类型// 最多可上传几个文件,默认为 5maxNumberOfFiles: 3,allowedFileTypes: ["mpeg/*","avi/*","navi/*","asf/*","wmv/*","mov/*","3gp/*","mp4/*","m4v/*","vob/*",], // 选择文件时的类型限制,默认为 ['video/*'] 。如不想限制,则设置为 []// 自定义上传参数,传递图片时需要带一些参数过去写在这。参数会被添加到 formData 中,一起上传到服务端。meta: {// token: 'xxx',// otherKey: 'yyy'},// 自定义设置请求头,比如添加token之类的headers: {// Accept: 'text/x-json',// otherKey: 'xxx'},metaWithUrl: false, // 将 meta 拼接到 url 参数中,默认 falsewithCredentials: true, // 跨域是否传递 cookie ,默认为 false//上传之前触发onBeforeUpload(file) {// file 选中的文件,格式如 { key: file }this.Message({message: "视频正在上传中,请耐心等待",duration: 0,customClass: "uploadTip",iconClass: "el-icon-loading",showClose: true,});return file;// 可以 return// 1. return file 或者 new 一个 file ,接下来将上传// 2. return false ,不上传这个 file},// 自定义插入视频customInsert(res, insertFn) {// 因为自定义插入导致onSuccess与onFailed回调函数不起作用,自己手动处理// 先关闭等待的Messagethis.Message.closeAll();if (res.code === 200) {this.Message.success({message: `${res.data.originalName} 上传成功`,});} else {this.Message.error({message: `${res.data.originalName} 上传失败,请重新尝试`,});}insertFn(res.data.link, res.data.link);},// 上传进度的回调函数,可以用来显示进度条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);},// 插入图片到富文本编辑器回显// customInsert(res, insertFn) {// console.log(res, '视频插入')// res 即服务端的返回结果// let url = res.data.url;// let poster = res.data.poster;// 从 res 中找到 url poster ,然后插入//参数url是视频地址,poster是视频封面图片,后端如果不返回,可以考虑写死一个固定的封面图// insertFn(url, poster)// }},},},// 默认编辑栏的配置jsonContent: [{type: "paragraph",children: [{ text: "", fontSize: "17px" }],// lineHeight ,关于默认行高的设置,可查看源码或通过官方demo// https://www.wangeditor.com/demo/index.html// 输入文字,设置默认字体、行高之后 在控制台输入 ,this.editor.children 会显示如下内容:/**[{"type": "paragraph", "children": [ { "text": "faskdfjaslkdfj" } ], "lineHeight": "2.5" } ]* 按对应格式设置 jsonContent 即可* */fontSize: "17px",lineHeight: 1.75,color: "#4a4a4a",},// {// type: 'image',// imageWidth100: true// }],mode: "default", // or 'simple'};},mounted() {},methods: {//获取oss阿里云图上传的client// getClient() {// return new Promise((resolve) => {// getOss({})// .then((res) => {// // console.log(res.data)// const OSS = require("ali-oss");// let clinet = new OSS({// accessKeyId: xxx,// accessKeySecret: xxx,// bucket: "xxx",// region: "xxx",// stsToken: xxx,// });// resolve(clinet);// })// .catch((error) => {// resolve(error.message);// });// });// },// wangeditor的方法---必须要用onCreated(editor) {this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错},},computed: {},components: { Editor, Toolbar },activated() {// console.log('actived')let docClasses = document.body.classList;docClasses.add("white-content");},deactivated() {// console.log('deactivated')let docClasses = document.body.classList;docClasses.remove("white-content");},beforeDestroy() {const editor = this.editor;if (editor == null) return;editor.destroy(); // 组件销毁时,及时销毁编辑器},
});
</script><style src="@wangeditor/editor/dist/css/style.css"></style><style>
* {margin: 0;padding: 0;
}
#tool-container {display: flex;justify-content: center;
}
.el-input__inner {width: 748px;border: none;font-size: 24px;font-weight: 500;padding: 0;color: #4a4a4a;
}
</style>
上传地址,各自配置。有错误欢迎大佬指教!私必回