1.其實element-admin中已經整合了tinyMce 富文本的配置,可是再項目需求中須要本身上傳本地圖片,就像這樣(用黴黴來鎮樓)html
2.本次項目上傳圖片的思想:先拿到本地的圖片轉換爲base64 的格式,傳遞給後端,後端保存後再返回給咱們一個圖片地址,最終咱們須要的就是這個地址作顯示和保存vue
具體的操做:由於安裝和基本的富文本配置都由elementui +admin 給咱們作了,我這裏主要是再貼一些本次我用到的工具和配置web
1)plugins:後端
const plugins= ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount ']
2)工具條 toolbarapi
const toolbar = ['searchreplace fontselect formatselect fontsizeselect bold italic underline strikethrough forecolor backcolor', ' hr alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscriptcode codesample bullist numlist ', ' table link image charmap preview anchor pagebreak insertdatetime media emoticons fullscreen ']
3)最後全部的配置,和圖片的上傳app
export default { name: 'Tinymce', // components: { editorImage }, props: { id: { type: String, default: function () { return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') } }, value: { type: String, default: '' }, config: { type: Object, default: () => { return { theme: 'modern', height: 400 } } }, toolbar: { type: Array, required: false, default () { return [] } }, accept: { default: 'image/jpeg, image/png', type: String }, url: { default: '', type: String }, maxSize: { default: 2097152, type: Number }, withCredentials: { default: false, type: Boolean }, menubar: { type: String, default: 'file edit insert view format table' }, height: { type: [Number, String], required: false, default: 360 }, width: { type: [Number, String], required: false, default: 'auto' } }, data () { return { Value: '', Url: '', upLoadBaseURL: 'process.env.VUE_APP_BASE_API', hasChange: false, hasInit: false, tinymceId: this.id, fullscreen: false, languageTypeList: { 'zh': 'zh_CN', 'en': 'en', 'es': 'es_MX', 'ja': 'ja' }, api: { uploadImage: "/api/imageUpload" }, } }, computed: { containerWidth () { const width = this.width if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'` return `${width}px` } return width } }, watch: { value (val) { if (!this.hasChange && this.hasInit) { this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val || '')) } } }, mounted () { this.init() }, activated () { if (window.tinymce) { this.initTinymce() } }, deactivated () { this.destroyTinymce() }, destroyed () { this.destroyTinymce() }, methods: { init () { // dynamic load tinymce from cdn load(tinymceCDN, (err) => { if (err) { this.$message.error(err.message) return } this.initTinymce() }) }, initTinymce () { // const _this = this const _this = this window.tinymce.init({ selector: `#${this.tinymceId}`, language: this.languageTypeList['zh'], height: this.height, body_class: 'panel-body ', object_resizing: false, toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, menubar: this.menubar, plugins: plugins, end_container_on_empty_block: true, powerpaste_word_import: 'clean', code_dialog_height: 450, code_dialog_width: 1000, advlist_bullet_styles: 'square', advlist_number_styles: 'default', imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'], default_link_target: '_blank', link_title: false, // CONFIG: Paste 粘貼 paste_retain_style_properties: 'all', paste_word_valid_elements: '*[*]', // word須要它 paste_data_images: true, // 粘貼的同時能把內容裏的圖片自動上傳,很是強力的功能 paste_convert_word_fake_lists: false, // 插入word文檔須要該屬性 paste_webkit_styles: 'all', paste_merge_formats: true, nonbreaking_force_tab: false, paste_auto_cleanup_on_paste: false, // CONFIG: ContentStyle 這塊很重要, 在最後呈現的頁面也要寫入這個基本樣式保證先後一致, `table`和`img`的問題基本就靠這個來填坑了 content_style: ` * { padding:0; margin:0; } html, body { height:100%; } img { max-width:100%; display:block;height:auto; } a { text-decoration: none; } iframe { width: 100%; } p { line-height:1.6; margin: 0px; } table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; } .mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; } ul,ol { list-style-position:inside; } `, insert_button_items: 'image link | inserttable', // CONFIG: StyleSelect style_formats: [ { title: '首行縮進', block: 'p', styles: { 'text-indent': '2em' } }, { title: '行高', items: [ { title: '1', styles: { 'line-height': '1' }, inline: 'span' }, { title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span' }, { title: '2', styles: { 'line-height': '2' }, inline: 'span' }, { title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span' }, { title: '3', styles: { 'line-height': '3' }, inline: 'span' } ] } ], // FontSelect font_formats: ` 微軟雅黑=微軟雅黑; 宋體=宋體; 黑體=黑體; 仿宋=仿宋; 楷體=楷體; 隸書=隸書; 幼圓=幼圓; Andale Mono=andale mono,times; Arial=arial, helvetica, sans-serif; Arial Black=arial black, avant garde; Book Antiqua=book antiqua,palatino; Comic Sans MS=comic sans ms,sans-serif; Courier New=courier new,courier; Georgia=georgia,palatino; Helvetica=helvetica; Impact=impact,chicago; Symbol=symbol; Tahoma=tahoma,arial,helvetica,sans-serif; Terminal=terminal,monaco; Times New Roman=times new roman,times; Trebuchet MS=trebuchet ms,geneva; Verdana=verdana,geneva; Webdings=webdings; Wingdings=wingdings,zapf dingbats`, // Tab tabfocus_elements: ':prev,:next', object_resizing: true, // Image imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions', nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin init_instance_callback: editor => { if (_this.value) { editor.setContent(_this.value) } _this.hasInit = true editor.on('NodeChange Change KeyUp SetContent', () => { this.hasChange = true this.$emit('input', editor.getContent()) }) }, setup (editor) { //自定義功能 editor.on('FullscreenStateChanged', (e) => { _this.fullscreen = e.state }) }, // ....上傳圖片配置代碼 images_upload_handler: (blobInfo, success, failure) => { var reader = new FileReader(); reader.readAsDataURL(blobInfo.blob()); reader.onload = function () { raceApi.postImgUrl({ image: this.result }).then(res => { //這裏就是要上傳base64 格式的圖片的請求了 if (res.code == 200) { let url = res.data.domain + res.data.path success(url) console.log(url); } }) } }, // prop內傳入的的config ...this.config, content_style: 'img {max-width:100% !important }', // 初始化賦值 這個主要是防止圖片拉昇變形的 (上傳的圖片再app顯示會變形要加上這個) setup: (editor) => { // 拋出 'on-ready' 事件鉤子 editor.on( 'init', () => { _this.loading = false _this.$emit('on-ready') editor.setContent(_this.value) } ) // 拋出 'input' 事件鉤子,同步value數據 editor.on( 'input change undo redo', () => { _this.$emit('input', editor.getContent()) } ) } }) }, destroyTinymce () { const tinymce = window.tinymce.get(this.tinymceId) if (this.fullscreen) { tinymce.execCommand('mceFullScreen') } if (tinymce) { tinymce.destroy() } }, setContent (value) { window.tinymce.get(this.tinymceId).setContent(value) }, getContent () { window.tinymce.get(this.tinymceId).getContent() }, imageSuccessCBK (arr) { const _this = this arr.forEach(v => { window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`) }) } } } `