|
@@ -0,0 +1,200 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div>
|
|
|
+ <Toolbar style="border: 1px solid black; border-bottom: 1px solid #ccc;" :editor="editor"
|
|
|
+ :defaultConfig="toolbarConfig" :mode="mode"/>
|
|
|
+ </div>
|
|
|
+ <div class="editor">
|
|
|
+ <Editor
|
|
|
+ :style="height"
|
|
|
+ v-model="html"
|
|
|
+ :defaultConfig="editorConfig"
|
|
|
+ :mode="mode"
|
|
|
+ @onCreated="onCreated"
|
|
|
+ @onChange="onChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import {Boot} from "@wangeditor/editor";
|
|
|
+import attachmentModule from "@wangeditor/plugin-upload-attachment";
|
|
|
+import {Editor, Toolbar} from "@wangeditor/editor-for-vue";
|
|
|
+import "@wangeditor/editor/dist/css/style.css";
|
|
|
+import axios from "axios";
|
|
|
+import {getToken} from "@/utils/auth";
|
|
|
+
|
|
|
+Boot.registerModule(attachmentModule);
|
|
|
+
|
|
|
+export default {
|
|
|
+ components: {Editor, Toolbar},
|
|
|
+ name: "MyEditor",
|
|
|
+ props: {
|
|
|
+ //border
|
|
|
+ border: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ /* 编辑器的内容 */
|
|
|
+ value: {
|
|
|
+ type: String,
|
|
|
+ default: "",
|
|
|
+ },
|
|
|
+ // 高度
|
|
|
+ height: {
|
|
|
+ type: String,
|
|
|
+ default: () => "500px",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ token: "Bearer " + getToken(),
|
|
|
+ editor: null,
|
|
|
+ html: "",
|
|
|
+ toolbarConfig: {
|
|
|
+ // excludeKeys: ["fullScreen","insertVideo","group-video"],
|
|
|
+ excludeKeys: ["fullScreen"],
|
|
|
+ insertKeys: {
|
|
|
+ index: 24,
|
|
|
+ keys: ["uploadAttachment"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ editorConfig: {
|
|
|
+ placeholder: "请输入内容...",
|
|
|
+ scroll: false,
|
|
|
+ MENU_CONF: {
|
|
|
+ uploadImage: {
|
|
|
+ // 自定义上传图片 方法
|
|
|
+ customUpload: this.uploadImg,
|
|
|
+ // 上传接口设置文件名
|
|
|
+ fieldName: "file",
|
|
|
+ meta: {
|
|
|
+ token: this.token,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ uploadVideo: {
|
|
|
+ customUpload: this.uploadVideo,
|
|
|
+ fieldName: "file",
|
|
|
+ meta: {
|
|
|
+ token: this.token,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ uploadAttachment: {
|
|
|
+ customUpload: this.uploadFile,
|
|
|
+ fieldName: "file",
|
|
|
+ meta: {
|
|
|
+ token: this.token,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ hoverbarKeys: {
|
|
|
+ attachment: {
|
|
|
+ menuKeys: ["downloadAttachment"],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址 一定要写ip+端口 不要写localhost
|
|
|
+ mode: "default", //default or 'simple'
|
|
|
+ };
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ value: {
|
|
|
+ handler(val) {
|
|
|
+ this.html = val;
|
|
|
+ },
|
|
|
+ immediate: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ // 模拟 ajax 请求,异步渲染编辑器
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ const editor = this.editor;
|
|
|
+ if (editor == null) return;
|
|
|
+ editor.destroy(); // 组件销毁时,及时销毁编辑器
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ onChange(editor) {
|
|
|
+ this.$emit("input", this.html);
|
|
|
+ },
|
|
|
+ onCreated(editor) {
|
|
|
+ this.editor = Object.seal(editor); // 一定要用 Object.seal() ,否则会报错
|
|
|
+ },
|
|
|
+ uploadImg(file, insertFn) {
|
|
|
+ let imgData = new FormData();
|
|
|
+ imgData.append("file", file);
|
|
|
+ axios.post(this.uploadUrl,
|
|
|
+ imgData,
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'content-Type': 'multipart/form-data',
|
|
|
+ "Authorization": this.token,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ insertFn(res.data.url);
|
|
|
+ } else {
|
|
|
+ this.$message.warning(res.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ uploadVideo(file, insertFn) {
|
|
|
+ let imgData = new FormData();
|
|
|
+ imgData.append("file", file);
|
|
|
+ axios.post(this.uploadUrl,
|
|
|
+ imgData,
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'content-Type': 'multipart/form-data',
|
|
|
+ "Authorization": this.token,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ // insertFn(`<video src="${res.data.url}" style="width: 100px; height: 100px;"></video>`);
|
|
|
+ insertFn(res.data.url);
|
|
|
+ console.log("insertFn",insertFn)
|
|
|
+ } else {
|
|
|
+ this.$message.warning(res.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ uploadFile(file, insertFn) {
|
|
|
+ let imgData = new FormData();
|
|
|
+ imgData.append("file", file);
|
|
|
+ axios.post(this.uploadUrl,
|
|
|
+ imgData,
|
|
|
+ {
|
|
|
+ headers: {
|
|
|
+ 'content-Type': 'multipart/form-data',
|
|
|
+ "Authorization": this.token,
|
|
|
+ },
|
|
|
+ }).then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ insertFn(
|
|
|
+ `附件:${res.data.originalFilename}`, res.data.url);
|
|
|
+ } else {
|
|
|
+ this.$message.warning(res.msg);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style scoped>
|
|
|
+.editor, .ql-toolbar {
|
|
|
+ white-space: pre-wrap !important;
|
|
|
+ line-height: normal !important;
|
|
|
+ height: 300px;
|
|
|
+ overflow-y: auto;
|
|
|
+ border: 1px solid black;
|
|
|
+}
|
|
|
+
|
|
|
+.border-line {
|
|
|
+ border: 1px solid #d6d6d6;
|
|
|
+}
|
|
|
+.w-e-scroll > div:first-child {
|
|
|
+ height: 100%;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+</style>
|