vue tinymce富文字編輯器封裝
阿新 • • 發佈:2022-12-05
<template> <div style="position: relative;"> <div style="text-align: right; margin-bottom: 20px;"> <el-popover placement="right" width="490" class="popoverbtn" trigger="click" @show="showData"> <div class="popCon"> <div class="poptop"> <el-button v-for=" item in popData" :key="item" type="primary" class="spanDel" size="mini" plain @click="popClick(item)">{{ item.tempKey }}<i class="el-icon-delete" @click.stop.prevent="delPop(item)"/></el-button> </div> <div class="popbtm"> <el-form ref="formInlineres" :inline="true" :rules="formInlinerules" :model="formInline" class="demo-form-inline"> <el-form-item label="名稱" prop="tempKey"> <el-input v-model="formInline.tempKey" size="mini" placeholder="請輸入名稱"/> </el-form-item> <el-form-item label="值" prop="tempValue"> <el-input v-model="formInline.tempValue" size="mini" placeholder="請輸入值"/> </el-form-item> <el-form-item> <el-button type="primary" size="mini" @click="onSubmit">新增</el-button> </el-form-item> </el-form> </div> </div> <el-button slot="reference" type="primary" icon="el-icon-edit" circle/> </el-popover> <el-upload ref="fileRefs" :before-upload="beforeUpload" :show-file-list="false" :disabled="disabled" class="uploadBtn" style="display:none" action="" accept=".docx" > <el-button :disabled="disabled">匯入</el-button> </el-upload> </div> <editor v-model="content" :init="init" :disabled="disabled" @onClick="onClick"/> </div> </template> <script> import 'mammoth/mammoth.browser.js' import Mammoth from 'mammoth' import tinymce from 'tinymce/tinymce' import Editor from '@tinymce/tinymce-vue' import 'tinymce/themes/silver' import 'tinymce/icons/default/icons' import 'tinymce/themes/silver' import 'tinymce/plugins/image' import 'tinymce/plugins/media' import 'tinymce/plugins/table' import 'tinymce/plugins/lists' import 'tinymce/plugins/contextmenu' import 'tinymce/plugins/wordcount' import 'tinymce/plugins/colorpicker' import 'tinymce/plugins/textcolor' import 'tinymce/plugins/preview' import 'tinymce/plugins/code' import 'tinymce/plugins/link' import 'tinymce/plugins/advlist' import 'tinymce/plugins/codesample' import 'tinymce/plugins/hr' import 'tinymce/plugins/fullscreen' import 'tinymce/plugins/textpattern' import 'tinymce/plugins/searchreplace' import 'tinymce/plugins/autolink' import 'tinymce/plugins/directionality' import 'tinymce/plugins/visualblocks' import 'tinymce/plugins/visualchars' import 'tinymce/plugins/template' import 'tinymce/plugins/charmap' import 'tinymce/plugins/nonbreaking' import 'tinymce/plugins/insertdatetime' import 'tinymce/plugins/imagetools' import 'tinymce/plugins/autosave' import 'tinymce/plugins/autoresize' import { tempLabelqueryAll, tempLabelinsert, popremove } from '@/api/tempmanage/mbglMbdz' // import { uploadFile } from '@/api/system/upload' // 擴充套件外掛 // import "../assets/tinymce/plugins/lineheight/plugin"; export default { // name: 'imcoder-tinymce', components: { Editor }, props: { value: { type: String, default: '' }, disabled: { type: Boolean, default: false }, plugins: { type: [String, Array], default: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr nonbreaking insertdatetime advlist lists wordcount imagetools textpattern autosave bdmap autoresize lineheight' }, toolbar: { type: [String, Array], default: 'code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link codesample | alignleft aligncenter alignright alignjustify outdent indent lineheight formatpainter | \ styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ table image media charmap hr pagebreak insertdatetime | bdmap fullscreen preview| importbtn' } }, data() { return { // 初始化配置 init: { _target: () => this, language_url: '/static/langs/zh_CN.js', language: 'zh_CN', skin_url: '/static/skins/ui/oxide', height: 770, min_height: 770, max_height: 770, toolbar_mode: 'wrap', plugins: this.plugins, toolbar: this.toolbar, content_style: 'p {margin: 5px 0;}', fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px', font_formats: '微軟雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;蘋果蘋方=PingFang SC,Microsoft YaHei,sans-serif;宋體=simsun,serif;仿宋體=FangSong,serif;黑體=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;', branding: false, setup: (editor) => { const _this = this editor.ui.registry.addButton('importbtn', { text: '匯入word', // icon:'material', onAction: function() { console.log('選擇文字') _this.$refs['fileRefs'].$refs['upload-inner'].handleClick() } }) }, paste_data_images: true, // 此處為圖片上傳處理函式,這個直接用了base64的圖片形式上傳圖片, // 如需ajax上傳可參考https://www.tiny.cloud/docs/configure/file-image-upload/#images_upload_handler file_picker_callback: function(callback, value, meta) { // 檔案分類 let filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4' // 為不同外掛指定檔案型別及後端地址 switch (meta.filetype) { case 'image': filetype = '.jpg, .jpeg, .png, .gif' break case 'media': filetype = '.mp3, .mp4' break case 'file': default: } // 模擬出一個input用於新增本地檔案 const input = document.createElement('input') input.setAttribute('type', 'file') input.setAttribute('accept', filetype) input.click() input.onchange = function() { const file = this.files[0] const formData = new FormData() formData.append('file', file, file.name) // xhr.send(formData); // uploadFile(formData).then(response=>{ // callback('http://10.50.0.174:8091'+response.data.network); // }) } } }, content: this.value, popData: [], formInline: { tempKey: '', tempValue: '' }, formInlinerules: { tempKey: [{ required: true, message: '名稱不能為空', trigger: 'blur' }], tempValue: [{ required: true, message: '值不能為空', trigger: 'blur' }] } } }, watch: { value(newValue) { // console.log(newValue) this.content = newValue }, content(newValue) { // console.log('11') // console.log(newValue) this.$emit('input', newValue) } }, mounted() { tinymce.init({}) }, methods: { beforeUpload(file) { const self = this var reader = new FileReader() reader.onloadend = function(event) { console.log(event) const arrayBuffer = reader.result // 將word 轉換成html const loading = self.$loading({ lock: true, text: '檔案解析中....', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.3)' }) Mammoth.convertToHtml({ arrayBuffer: arrayBuffer }).then(function( resultObject ) { // 重要!不適用setTimeout,無法使用 setTimeout(() => { // 獲取原來編輯器的內容 const content = tinymce.activeEditor.getContent() + resultObject.value tinymce.activeEditor.setContent(content) loading.close() }, 100) }) } reader.readAsArrayBuffer(file) return false }, // 模組資訊新增 onSubmit() { if (this.formInline.tempKey && this.formInline.tempValue) { tempLabelinsert(this.formInline).then(res => { this.formInline.tempKey = '' this.formInline.tempValue = '' this.popQuery() this.$message({ type: 'success', message: '新增成功' }) }) } else { this.$message({ type: 'warning', message: '名稱和值不能為空' }) } }, // 模組資訊插入 popClick(item) { const text = item.tempValue // 獲取編輯器物件 // eslint-disable-next-line no-undef tinyMCE.execCommand('mceInsertContent', false, text) }, showData() { const _this = this tempLabelqueryAll().then(res => { console.log(res) _this.popData = res.data.data }) }, delPop(item) { this.$confirm('確定將選擇資料刪除?', { confirmButtonText: '確定', cancelButtonText: '取消', type: 'warning' }) .then(() => { return popremove(item.id) }) .then(() => { this.showData() this.$message({ type: 'error', message: '已刪除!' }) }) } } } </script> <style lang="scss" scoped> #textAreaTemplate { .uploadBtn { display: inline-block; margin: 0 10px; } .tabTiyle { border-left: 8px solid rgba(36, 145, 255, 1); padding-left: 15px; font-size: 21px; text-align: left; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: rgba(0, 0, 0, 0.87); } } </style> <style lang="scss" scoped> .dialog { text-align: left; } /deep/ .popoverbtn{ position: absolute; z-index: 1000; right: 6px; top: 4px; } .spanDel{ position: relative; .el-icon-delete{ position: absolute; top: -5px; right: -5px; background: red; display: none; z-index: 9999999; } } .spanDel:hover .el-icon-delete{ display: block; } .popCon{ display: flex; height: 300px; flex-flow: column; } .poptop{ flex: 5; } .popbtm{ flex: 1; } /deep/ .el-button--mini, .el-button--mini.is-round{ margin: 1%; } /deep/ .ql-editor{ padding: 0!important; } </style>