First install wangeditor/editor-for-vue (node version problem plus –legacy-peer-deps, otherwise the installation will not work)
npm install @wangeditor/editor-for-vue –save –legacy-peer-deps
This is the packaged file upload interface
// file upload uploadImg: file => { const formData = new FormData() formData.append('files', file) return request({ url: '/upload/uploadFile', method: 'POST', data: formData, headers: { 'Content-Type': 'multipart/form-data' } }) }
Encapsulated component code
<template> <div style="border: 1px solid #ccc" class="relative"> <div v-if="disabled" class="disable-layer" /> <Toolbar ref="toolbar" style="border-bottom: 1px solid #ccc" :editor="editor" :default-config="toolbarConfig" :mode="mode" /> <Editor style="overflow-y: hidden" :value="value" :default-config="editorConfig" :mode="mode" @input="handleInput" @onCreated="onCreated" /> </div> </template> <script> // import package import { Editor, Toolbar } from '@wangeditor/editor-for-vue' // Interface for uploading files import { videoApi } from '@/api/video' // Import the style of wangeditor/editor-for-vue import '@wangeditor/editor/dist/css/style.css' // The path prefix of the uploaded file import { baseUrl } from '@/utils/pictureUrl' export default { name: 'WangEditor', components: { Editor, Toolbar }, props: { value: String, disabled: Boolean, cusHeight: { type: String, default: '150px' } }, data() { return { editor: null, html: '', // Configuration of wangeditor/editor-for-vue toolbarConfig: { toolbarKeys: [ 'bold', 'underline', 'italic', 'through', 'clearStyle', 'color', 'bgColor', 'fontSize', 'justifyLeft', 'justifyRight', 'justifyCenter', 'justifyJustify', 'lineHeight', 'header1', 'header2', 'header3', 'header4', 'header5', 'bulletedList', 'numberedList', 'uploadImage' // "uploadVideo" ] }, editorConfig: { placeholder: 'Please enter content...', MENU_CONF: { uploadImage: { // custom image upload async customUpload(file, insertFn) { videoApi.uploadImg(file).then(response => { if (response. result == 1) { const url = baseUrl + response.msg // insert image into textbox insertFn(url) } }) } } // uploadVideo: { // // Custom image upload // async customUpload(file, insertFn) { // uploadFile('', file).then(response => { // const url = response.data // insertFn(this. $getFilePath(url)) // }) // } // } } }, mode: 'default' // or 'simple' } }, mounted() {}, created() {}, beforeDestroy() { const editor = this.editor if (editor == null) return editor.destroy() // Destroy the editor in time when the component is destroyed }, methods: { onCreated(editor) { this.editor = Object.seal(editor) // Be sure to use Object.seal(), otherwise an error will be reported // console.log('this.editor :>> ', this.editor.getAllMenuKeys()); }, handleInput(value) { console. log(value) // Pass the text content to the parent component (referencing the vue file of this component) this. $emit('input', value) } } } </script> <style lang="scss" scoped> .disable-layer { width: 100%; height: 100%; background: #f5f7fa; position: absolute; top: 0; left: 0; z-index: 99; opacity: 0.5; } </style>
Then the mani.js entry file can be registered and used globally
import myEditor from ‘@/components/myEditor/CusWangEditor.vue’
Vue. component(‘myEditor’, myEditor)
<template> <div> <el-card> <myEditor :value="initForm. content" @input="input" /> <div class="btn"><el-button type="primary" size="small" @click="submit">Save</el-button></div> </el-card> </div> </template> <script> import { contentApi } from '@/api/content' export default { name: 'Area', data() { return { // search postForm: { currentPage: 1, pageSize: 10 }, initForm: { content: '', plateId: 5, id: '' } } }, computed: {}, mounted() { this. loadData() }, methods: { // Store the content text content passed from myEditor rich text input(value) { this.initForm.content = value }, // save submit() { this.$confirm('Are you sure to save?', 'Prompt', { confirmButtonText: 'OK', cancelButtonText: 'Cancel', type: 'warning' }) .then(() => { contentApi.text(this.$filNull(this.initForm)).then(res => { const { result, msg } = res if (result == 1) { this. $message. success(msg) } else { this.$message.warning(msg) } }) }) .catch(() => { this. $message({ type: 'info', message: 'save canceled' }) }) }, // Get the text of area A of the eye valley loadData() { contentApi.getRichTextContent({ plateId: this.initForm.plateId }).then(res => { const { data, result, msg } = res if (result == 1) { this.initForm.content = data.content this.initForm.id = data.id } else { this.$message.warning(msg) } }) } } } </script> <style lang="scss" scoped> .dashboard { &-container { margin: 30px; } &-text { font-size: 30px; line-height: 46px; } } .btn { margin-top: 50px; display: flex; justify-content: center; } ::v-deep.ql-container { height: 500px !important; } </style>
That’s it
The most important thing is the following code
// import package import { Editor, Toolbar } from '@wangeditor/editor-for-vue' // Interface for uploading files import { videoApi } from '@/api/video' // Import the style of wangeditor/editor-for-vue import '@wangeditor/editor/dist/css/style.css' // The path prefix of the uploaded file import { baseUrl } from '@/utils/pictureUrl'
<template> <div style="border: 1px solid #ccc" class="relative"> <div v-if="disabled" class="disable-layer" /> <Toolbar ref="toolbar" style="border-bottom: 1px solid #ccc" :editor="editor" :default-config="toolbarConfig" :mode="mode" /> <Editor style="overflow-y: hidden" :value="value" :default-config="editorConfig" :mode="mode" @input="handleInput" @onCreated="onCreated" /> </div> </template>
MENU_CONF: { uploadImage: { // custom image upload async customUpload(file, insertFn) { // upload image videoApi.uploadImg(file).then(response => { if (response. result == 1) { const url = baseUrl + response.msg // Insert the picture into the text box (must remember to insertFn into the text box or it won't work) insertFn(url) } }) } } // uploadVideo: { // // Custom image upload // async customUpload(file, insertFn) { // uploadFile('', file).then(response => { // const url = response.data // insertFn(this. $getFilePath(url)) // }) // } // } }
beforeDestroy() { const editor = this.editor if (editor == null) return editor.destroy() // Destroy the editor in time when the component is destroyed }, methods: { onCreated(editor) { this.editor = Object.seal(editor) // Be sure to use Object.seal(), otherwise an error will be reported // console.log('this.editor :>> ', this.editor.getAllMenuKeys()); }, handleInput(value) { console. log(value) // Pass the text content to the parent component (referencing the vue file of this component) this. $emit('input', value) } }