🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
``` <el-row> <el-col> <span class="diver">详细内容</span> <div class="editor-container"> <tinymce :height=400 ref="editor" v-model="formValue.goods_contents"></tinymce> </div> </el-col> </el-row> ``` ``` import tinymce from "@/components/Tinymce" ``` ``` components: { tinymce }, ``` index.vue ``` E:/Vue7/shop805/src/components/Tinymce/index.vue ``` ``` <template> <div class="tinymce-container editor-container"> <textarea class="tinymce-textarea" id="tinymceId"></textarea> <div class="editor-custom-btn-container"> <editorImage color="#20a0ff" class="editor-upload-btn" @successCBK="imageSuccessCBK"></editorImage> </div> </div> </template> <script> import editorImage from './components/editorImage' export default { name: 'tinymce', components: { editorImage }, props: { value: { type: String, default: '' }, toolbar: { type: Array, required: false, default() { return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright '] } }, menubar: { default: '' }, height: { type: Number, required: false, default: 360 } }, data() { return { hasChange: false, hasInit: false, } }, watch: { value(val) { if (!this.hasChange && this.hasInit) { this.$nextTick(() => window.tinymce.get('tinymceId').setContent(val)) } } }, mounted() { this.initTinymce() }, activated() { this.initTinymce() }, deactivated() { this.destroyTinymce() }, methods: { initTinymce() { const _this = this window.tinymce.init({ selector: '#tinymceId', height: this.height, body_class: 'panel-body ', object_resizing: false, toolbar: this.toolbar, menubar: this.menubar, plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools ', // language: 'zh_CN', // language_url: 'http://cdn.masterjoy.top/zh_CN.js', forced_root_block: '', 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: ['wpimg.wallstcn.com', 'wallstreetcn.com'], imagetools_toolbar: 'watermark', default_link_target: '_blank', link_title: false, init_instance_callback: editor => { if (_this.value) { editor.setContent(_this.value) } _this.hasInit = true editor.on('NodeChange Change KeyUp', () => { this.hasChange = true this.$emit('input', editor.getContent({ format: 'raw' })) }) } // 整合七牛上传 // images_dataimg_filter(img) { // setTimeout(() => { // const $image = $(img); // $image.removeAttr('width'); // $image.removeAttr('height'); // if ($image[0].height && $image[0].width) { // $image.attr('data-wscntype', 'image'); // $image.attr('data-wscnh', $image[0].height); // $image.attr('data-wscnw', $image[0].width); // $image.addClass('wscnph'); // } // }, 0); // return img // }, // images_upload_handler(blobInfo, success, failure, progress) { // progress(0); // const token = _this.$store.getters.token; // getToken(token).then(response => { // const url = response.data.qiniu_url; // const formData = new FormData(); // formData.append('token', response.data.qiniu_token); // formData.append('key', response.data.qiniu_key); // formData.append('file', blobInfo.blob(), url); // upload(formData).then(() => { // success(url); // progress(100); // }) // }).catch(err => { // failure('出现未知问题,刷新页面,或者联系程序员') // console.log(err); // }); // }, }) }, destroyTinymce() { if (window.tinymce.get('tinymceId')) { window.tinymce.get('tinymceId').destroy() } }, setContent(value) { window.tinymce.get('tinymceId').setContent(value) }, getContent() { window.tinymce.get('tinymceId').getContent() }, imageSuccessCBK(arr) { arr.forEach(v => { window.tinymce.get('tinymceId').insertContent(`<img class="wscnph" src="${v.url}" >`) }) } }, destroyed() { this.destroyTinymce() } } </script> <style scoped> .tinymce-container { position: relative; } .tinymce-textarea { visibility: hidden; z-index: -1; } .editor-custom-btn-container { position: absolute; right: 15px; /*z-index: 2005;*/ top: 18px; } .editor-upload-btn { display: inline-block; } </style> ``` ``` components/Tinymce/components/editorImage.vue ``` ``` <template> <div class="upload-container"> <el-button icon='upload' :style="{background:color,borderColor:color}" @click=" dialogVisible=true" type="primary">上传图片 </el-button> <el-dialog :visible.sync="dialogVisible" title="上传图片"> <el-upload class="editor-slide-upload" :action="imgPostUrl" :multiple="true" :file-list="fileList" :show-file-list="true" list-type="picture-card" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="beforeUpload"> <el-button size="small" type="primary">点击上传</el-button> </el-upload> <el-button @click="dialogVisible = false">取 消</el-button> <el-button type="primary" @click="handleSubmit">确 定</el-button> </el-dialog> </div> </template> <script> // import { getToken } from 'api/qiniu' const api = process.env.BASE_API const cdn = process.env.CDN export default { name: 'editorSlideUpload', props: { color: { type: String, default: '#20a0ff' } }, data() { return { dialogVisible: false, listObj: {}, fileList: [], imgPostUrl: api + '/common/uploadImg', //图片上传地址 } }, methods: { checkAllSuccess() { return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess) }, handleSubmit() { const arr = Object.keys(this.listObj).map(v => this.listObj[v]) if (!this.checkAllSuccess()) { this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!') return } console.log(arr) this.$emit('successCBK', arr) this.listObj = {} this.fileList = [] this.dialogVisible = false }, handleSuccess(response, file) { const uid = file.uid const objKeyArr = Object.keys(this.listObj) for (let i = 0, len = objKeyArr.length; i < len; i++) { if (this.listObj[objKeyArr[i]].uid === uid) { this.listObj[objKeyArr[i]].url = cdn + response.data this.listObj[objKeyArr[i]].hasSuccess = true return } } }, handleRemove(file) { const uid = file.uid const objKeyArr = Object.keys(this.listObj) for (let i = 0, len = objKeyArr.length; i < len; i++) { if (this.listObj[objKeyArr[i]].uid === uid) { delete this.listObj[objKeyArr[i]] return } } }, beforeUpload(file) { const _self = this const _URL = window.URL || window.webkitURL const fileName = file.uid this.listObj[fileName] = {} return new Promise((resolve, reject) => { const img = new Image() img.src = _URL.createObjectURL(file) img.onload = () => { _self.listObj[fileName] = { hasSuccess: false, uid: file.uid, width: this.width, height: this.height } } resolve(true) }) } } } </script> <style rel="stylesheet/scss" lang="scss" scoped> .upload-container { .editor-slide-upload { margin-bottom: 20px; } } </style> ```