| | |
| | | <template> |
| | | <div style="border: 1px solid #ccc;"> |
| | | <div class="wang_editor"> |
| | | <Toolbar |
| | | style="border-bottom: 1px solid #ccc" |
| | | :editor="editor" |
| | | :defaultConfig="toolbarConfig" |
| | | :default-config="toolbarConfig" |
| | | :mode="mode" |
| | | /> |
| | | <Editor |
| | | style="height: 300px; overflow-y: hidden;" |
| | | :value="content.content" |
| | | v-model="html" |
| | | style="min-height: 200px" |
| | | :default-config="editorConfig" |
| | | :mode="mode" |
| | | :defaultConfig="editorConfig" |
| | | @onCreated="onCreated" |
| | | @onChange="onChange" |
| | | @input="html=$event" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import { Editor, Toolbar } from '@wangeditor/editor-for-vue' |
| | | import '@wangeditor/editor/dist/css/style.css' |
| | | import axios from 'axios' |
| | | |
| | | import { uploadFile } from '@/api' |
| | | |
| | | const uploadConfig = { |
| | | action: uploadFile, // 必填参数 图片上传地址 |
| | | methods: 'POST', // 必填参数 图片上传方式 |
| | | token: '', // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage |
| | | name: 'file', // 必填参数 文件的参数名 |
| | | size: 500, // 可选参数 图片大小,单位为Kb, 1M = 1024Kb |
| | | accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可选 可上传的图片格式 |
| | | } |
| | | export default { |
| | | name: 'RichEditor', |
| | | components: { Editor, Toolbar }, |
| | | components: { |
| | | Editor, |
| | | Toolbar |
| | | }, |
| | | props: { |
| | | content: { |
| | | type: Object, |
| | | default: () => {} |
| | | info: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | default: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | placeholder: { |
| | | type: String, |
| | | default: '请输入内容...' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | editor: null, |
| | | html: '<p><br></p>', |
| | | toolbarConfig: { |
| | | toolbarKeys: [ |
| | | "headerSelect", |
| | | "blockquote", |
| | | "|", |
| | | "bold", |
| | | "underline", |
| | | "italic", |
| | | { |
| | | "key": "group-more-style", |
| | | "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": [ |
| | | "through", |
| | | "code", |
| | | "sup", |
| | | "sub", |
| | | "clearStyle" |
| | | ] |
| | | }, |
| | | "color", |
| | | "bgColor", |
| | | "|", |
| | | "fontSize", |
| | | "fontFamily", |
| | | "lineHeight", |
| | | "|", |
| | | "bulletedList", |
| | | "numberedList", |
| | | "todo", |
| | | { |
| | | "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", |
| | | "justifyRight", |
| | | "justifyCenter", |
| | | "justifyJustify" |
| | | ] |
| | | }, |
| | | { |
| | | "key": "group-indent", |
| | | "title": "缩进", |
| | | "iconSvg": "<svg viewBox=\"0 0 1024 1024\"><path d=\"M0 64h1024v128H0z m384 192h640v128H384z m0 192h640v128H384z m0 192h640v128H384zM0 832h1024v128H0z m0-128V320l256 192z\"></path></svg>", |
| | | "menuKeys": [ |
| | | "indent", |
| | | "delIndent" |
| | | ] |
| | | }, |
| | | // "|", |
| | | "emotion", |
| | | "insertLink", |
| | | { |
| | | "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" |
| | | ] |
| | | }, |
| | | "insertTable", |
| | | "codeBlock", |
| | | "divider", |
| | | "|", |
| | | "undo", |
| | | "redo", |
| | | "|", |
| | | "fullScreen" |
| | | ] |
| | | }, |
| | | toolbarConfig: {}, |
| | | editorConfig: { |
| | | placeholder: '请输入内容...', |
| | | placeholder: this.placeholder, |
| | | MENU_CONF: { |
| | | uploadImage: { |
| | | // server: '/api/upload', |
| | | name: 'file', |
| | | server: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/uploadLocal', |
| | | html: this.info, |
| | | server: uploadFile, |
| | | // 单个文件的最大体积限制,默认为 2M |
| | | maxFileSize: 5 * 1024 * 1024, // 1M |
| | | // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 [] |
| | | allowedFileTypes: ['image/*'], |
| | | // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端 |
| | | meta: { |
| | | folder: 'shop' |
| | | token: '', |
| | | otherKey: '', |
| | | folder: 'COURSE_IMG' |
| | | }, |
| | | onBeforeUpload(file) { // JS 语法 |
| | | // file 选中的文件,格式如 { key: file } |
| | | // debugger |
| | | return file |
| | | // 自定义增加 http header |
| | | headers: { |
| | | token: localStorage.getItem('token') || '' |
| | | // Accept: 'text/x-json', |
| | | // otherKey: 'xxx' |
| | | }, |
| | | onSuccess(file, res) { |
| | | // 跨域是否传递 cookie ,默认为 false |
| | | withCredentials: true, |
| | | // 超时时间,默认为 10 秒 |
| | | timeout: 5 * 1000, // 5 秒 |
| | | onSuccess (file, res) { // TS 语法 |
| | | // onSuccess(file, res) { // JS 语法 |
| | | console.log(`${file.name} 上传成功`, res) |
| | | }, |
| | | onError(file, err, res) { |
| | | console.log(`${file.name} 上传出错`, err, res) |
| | | }, |
| | | }, |
| | | customUpload (file, insertFn) { // TS 语法 |
| | | // file 即选中的文件 |
| | | // 自己实现上传,并得到图片 url alt href |
| | | // var form = new FormData() |
| | | // form.append('image', file) |
| | | // form.append('folder', 'COURSE_IMG') |
| | | var formData = new FormData() |
| | | formData.append(file.name, file) |
| | | formData.append('image', file) |
| | | formData.append('folder', 'member') |
| | | // formData.append('type', '') |
| | | |
| | | var xhr = new XMLHttpRequest() |
| | | xhr.open(uploadConfig.methods, uploadConfig.action, true) |
| | | // 上传数据成功,会触发 |
| | | xhr.send(formData) |
| | | xhr.onreadystatechange = () => { |
| | | // 若响应完成且请求成功 |
| | | if (xhr.readyState === 4 && xhr.status === 200) { |
| | | const result = JSON.parse(xhr.responseText) |
| | | console.log('result', result); |
| | | insertFn(result.data.url, '', result.data.url) |
| | | } |
| | | } |
| | | }, |
| | | mode: 'default', // or 'simple' |
| | | customInsert (res, insertFn) { // TS 语法 |
| | | // customInsert(res, insertFn) { // JS 语法 |
| | | // res 即服务端的返回结果 |
| | | console.log(res.data.url) |
| | | // 从 res 中找到 url alt href ,然后插入图片 |
| | | insertFn(res.url) |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | mode: 'default' // or 'simple' |
| | | } |
| | | }, |
| | | emits: ['input'], |
| | | computed: { |
| | | html: { |
| | | get () { |
| | | return this.info || '' |
| | | }, |
| | | set (newValue) { |
| | | this.$emit('input', newValue) |
| | | } |
| | | } |
| | | }, |
| | | mounted () { |
| | | setTimeout(() => { |
| | | this.info = this.default |
| | | }, 1200) |
| | | }, |
| | | beforeDestroy() { |
| | | const editor = this.editor |
| | |
| | | }, |
| | | methods: { |
| | | onCreated (editor) { |
| | | this.editor = Object.seal(editor) |
| | | this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错 |
| | | this.$emit('input', '123123') |
| | | }, |
| | | onChange (editor) { |
| | | console.log(this.html); |
| | | // debugger |
| | | if (!this.html||this.content.content==this.html) { |
| | | return |
| | | test () { |
| | | console.log(this.info) |
| | | } |
| | | this.$emit('edit', this.html) |
| | | }, |
| | | }, |
| | | |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style src="@wangeditor/editor/dist/css/style.css"></style> |
| | | <style lang="scss" scoped> |
| | | .wang_editor { |
| | | border: 1px solid; |
| | | } |
| | | </style> |