| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- <template>
- <div class="tinymce-box">
- <div id="mytoolbar" class="mytoolbar"></div>
- <div class="box">
- <div class="tit"><input id="tinymceTitle" type="text" v-model="article_title" placeholder="请输入标题" /></div>
- <client-only>
- <editor id="tinymce" class="doc-cnt" v-model="contents" :init="init"></editor>
- </client-only>
- </div>
- <div class="editor-custom-btn-container">
- <editorImage color="#2973fd" ref="editorImage" class="editor-upload-btn" @successCBK="imageSuccessCBK"/>
- </div>
- </div>
- </template>
- <script>
- import editorImage from './editorImage'
- import editor from '@tinymce/tinymce-vue';
- import toolbar from "./toolbar"; // toolbar
- import plugins from "./plugins"; // plugins
- let tinymce;
- // 在客户端环境下引入
- if (process.client) {
- tinymce = require('tinymce/tinymce');
- require('tinymce/themes/silver');
- require('tinymce/icons/default');
- require('./formatpainter'); //格式刷
- require('tinymce/plugins/image');// 插入上传图片插件
- require('tinymce/plugins/imagetools');// 插入上传图片插件
- require('tinymce/plugins/media');// 插入视频插件
- require('tinymce/plugins/table');// 插入表格插件
- require('tinymce/plugins/lists');// 列表插件
- require('tinymce/plugins/link');//超链接插件
- require('tinymce/plugins/wordcount');// 字数统计插件
- require('tinymce/plugins/emoticons');// 插入表情插件
- require('tinymce/plugins/fullscreen');
- require('tinymce/plugins/code');
- require('tinymce/plugins/paste');
- require('tinymce/plugins/advlist');
- require('tinymce/plugins/autolink');
- require('tinymce/plugins/autosave');
- require('tinymce/plugins/codesample');
- require('tinymce/plugins/colorpicker');
- require('tinymce/plugins/contextmenu');
- require('tinymce/plugins/directionality');
- require('tinymce/plugins/nonbreaking');
- require('tinymce/plugins/insertdatetime');
- require('tinymce/plugins/preview');
- require('tinymce/plugins/charmap');
- require('tinymce/plugins/save');
- require('tinymce/plugins/searchreplace');
- require('tinymce/plugins/spellchecker');
- require('tinymce/plugins/tabfocus');
- require('tinymce/plugins/table');
- require('tinymce/plugins/template');
- require('tinymce/plugins/textcolor');
- require('tinymce/plugins/visualblocks');
- require('tinymce/plugins/textpattern');
- require('tinymce/plugins/visualchars');
- require('tinymce/plugins/wordcount');
- require('tinymce/plugins/anchor');
- require('tinymce/plugins/hr');
- require('tinymce/plugins/link');
- // require('tinymce/plugins/toc'); //标题大纲
- require('tinymce/plugins/noneditable');
- // require('tinymce/plugins/pagebreak'); //分页符
- }
- export default {
- name: "tinymce-editor",
- components:{editor, editorImage},
- // 接收引用此组件的值
- props: ['modifyContent'],
- data() {
- return {
- article_title: "",
- uploaded:false,//有没有上传完成
- //初始化配置
- init: {
- inline: true,
- fixed_toolbar_container: '#mytoolbar',
- toolbar_persist: true,
- // toolbar_sticky: true,
- // placeholder: "请输入文本",
- language_url: '/plugins/shop_server/static/tinymce/langs/zh_CN.js',// 语言包的路径
- language: 'zh_CN',//语言
- emoticons_database_url: '/plugins/shop_server/static/tinymce/emoticons/js/emojis.js',
- skin_url: '/plugins/shop_server/static/tinymce/skins/ui/oxide',// skin路径
- min_height: 800,//编辑器高度
- width: 1000,
- branding: false,//是否禁用“Powered by TinyMCE”
- elementpath: false, //隐藏底栏的元素路径
- menubar: false,//顶部菜单栏显示
- object_resizing: false,// 是否禁用表格图片大小调整
- autosave_ask_before_unload:false, // 去除关闭/刷新网页时弹出对话框
- plugins: plugins,
- toolbar: toolbar,
- toolbar_groups: {
- formatting: {
- text: '文字格式',
- tooltip: 'Formatting',
- items: 'bold italic underline strikethrough | superscript subscript | removeformat',
- },
- alignment: {
- icon: 'align-left',
- tooltip: 'alignment',
- items: 'alignleft aligncenter alignright alignjustify | outdent indent ',
- },
- insertion: {
- text: "插入",
- tooltip: 'insertion',
- items: 'codesample table insertdatetime anchor | charmap hr',
- },
- },
- body_class: "panel-body ",
- end_container_on_empty_block: true,
- powerpaste_word_import: "clean",
- code_dialog_height: 450,
- code_dialog_width: 1000,
- contextmenu: "link copy ", //右键菜单
- advlist_bullet_styles: "square",
- advlist_number_styles: "default",
- imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
- // 自定义字号
- fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 36px 48px 56px 72px',
- // 自定义字体集
- theme_advanced_fonts:
- "宋体=宋体;微软雅黑=微软雅黑;新宋体=新宋体;Courier New=courier new,courier,monospace;AkrutiKndPadmini=Akpdmi-n",
- paste_data_images: true, // 允许粘贴图像
- // 自定义字体
- font_formats: `
- 微软雅黑=微软雅黑;
- 宋体=宋体;
- 黑体=黑体;
- 仿宋=仿宋;
- 楷体=楷体;
- 隶书=隶书;
- 幼圆=幼圆;
- 思源黑体CN=思源黑体CN;
- 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`,
- content_style: `
- * { padding:0; margin:0; font-family: "Noto Sans SC";}
- html, body { height:100%; }
- img { max-width:100%; display:inline-block;height:auto; }
- a { text-decoration: none; }
- iframe { width: 100%; }
- p { line-height:1.6; margin: 0px; font-size: 16px; font-family:微软雅黑}
- 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; }
- body, td, pre {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 12px;
- }
- `,
- block_formats: 'Paragraph=p;Header 1=h1;Header 2=h2;Header 3=h3;Heading 4=h4;',
- // formats:{
- // h1:{block:'h1',attributes: { 'class': `yunzhong_title` }},
- // h2:{block:'h2',attributes: { 'class': `yunzhong_title` }},
- // },
- default_link_target: "_blank",
- link_title: false,
- convert_urls: false, // 图片上传路径为绝对路径
- remove_script_host: false,
- paste_word_valid_elements: "*[*]",
- paste_convert_word_fake_lists: false,
- paste_webkit_styles: "all",
- paste_merge_formats: true,
- nonbreaking_force_tab: false,
- paste_auto_cleanup_on_paste: false,
- forced_root_block: "p",
- force_p_newlines: true,
- importcss_append: true,
- tabfocus_elements: ":prev,:next",
- // 本地图片上传配置
- images_upload_handler: (blobInfo, success, failure) => {
- // 上传图片拿到url
- let fd = new FormData();
- fd.append('file', blobInfo.blob(), blobInfo.filename());
- this.uploadImg(fd, 'img').then((resVideo)=> {
- if(resVideo) {
- success(resVideo)
- }else {
- failure("上传失败")
- }
- });
- },
- // 本地媒体上传配置
- file_picker_types: 'media',
- file_picker_callback: (callback, value, meta)=> {
- if(meta.filetype == 'media'){
- let input = document.createElement('input');//创建一个隐藏的input
- input.setAttribute('type', 'file');
- input.setAttribute('accept', '.mp4,.mov,.avi');
- let that = this;
- input.onchange = function(){
- let file = this.files[0];//选取第一个文件
- that.uploadImg(file, 'video').then((resVideo)=> {
- callback(resVideo, { title: file.name,width:'100%',height:'100%' }) //将url显示在弹框输入框中
- }); // 上传视频拿到url
- };
- //触发点击
- input.click();
- }
- },
- save_onsavecallback: ()=> {
- // 触发保存事件
- this.$emit('save')
- },
- setup: (editor) => {
- const _this = this;
- // 定义按钮,
- editor.ui.registry.addButton('outline', {
- // text: '大纲',
- icon: "toc",
- tooltip: '大纲',
- onAction: () => {
- this.showOutline(editor)
- }
- });
- editor.ui.registry.addButton('manyimg', {
- icon: "gallery",
- tooltip: '多图',
- onAction: () => {
- this.opUpload()
- }
- });
- editor.ui.registry.addButton('fileupload', {
- icon: "non-breaking",
- tooltip: '上传附件',
- onAction: () => {
- this.fileUpload()
- }
- });
- // 监听编辑器失焦事件
- editor.on('blur', function () {
- _this.$emit('saveDraft')
- });
- // editor.on('keydown', function (e) {
- // if (e.keyCode == 83 && (navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)){
- // _this.$emit('save')
- // }
- // });
- },
- },
- // 绑定的内容
- contents: this.modifyContent
- }
- },
- mounted(){ // 用process.client判断一下环境再执行
- this.$nextTick(()=>{
- if (process.client) {
- window.tinymce.init({});
- }
- })
- },
- watch: {
- modifyContent(newValue) {
- this.contents = newValue
- },
- contents(newValue) {
- this.$emit('writeContent', newValue);
- },
- article_title(newValue) {
- this.$emit('writeTitle', newValue);
- }
- },
- methods: {
- setTitle(name) {
- this.article_title = name;
- },
- opUpload() {
- this.$refs.editorImage.opUpload('img')
- },
- fileUpload() {
- this.$refs.editorImage.opUpload('file')
- },
- showOutline(editor) {
- // editor.insertContent(' <b>It\'s my button!</b> ')
- this.$emit('showOutline')
- },
- uploadImg(file,type) {
- return new Promise((resolve, reject) => {
- let fd = new FormData();
- let loading = "loading"
- if(type === 'img') {
- fd = file;
- loading = "";
- }else if(type ==='video') {
- fd.append("upload_type", "videos");
- fd.append("file", file);
- }
- this.fun.$post(this.fun.getRealUrl("upload.uploadPic"), fd, loading,'', {
- headers: { "Content-Type": "multipart/form-data" }
- }).then((res) => {
- if(res.result == 1) {
- resolve(res.data.img_url)
- }else {
- reject('');
- console.log("上传出错")
- }
- }).catch(() => {
- reject('');
- console.log("上传出错")
- });
- })
- },
- imageSuccessCBK(obj) {
- console.log(obj);
- if(obj.uploadType === 'img') {
- obj.arr.forEach(v => {
- window.tinymce.get("tinymce").insertContent(`<img class="wscnph" style="display: inline-block;" src="${v.url}" />`)
- })
- }else if(obj.uploadType === 'file'){
- obj.arr.forEach(v => {
- v.url = v.url.replace(/http:/gi, "https:");
- window.tinymce.get("tinymce").insertContent(`<a target="_blank" class="pc-file" download="${v.name}" href="${v.url}"><i class="iconfont icon-all_link"> </i>${v.name}</a>`)
- })
- }else {
- obj.arr.forEach(v => {
- window.tinymce.get("tinymce").insertContent(`<video class="pc-video" src="${v.url}" ></video>`)
- })
- }
- }
- }
- }
- </script>
- <style lang="scss" rel="stylesheet/scss" scoped>
- .tinymce-box {
- line-height: normal;
- padding: 0 10px;
- }
- .toolbar {padding-bottom:10px;}
- .tox .tox-toolbar{background:none;}
- .tox-tinymce-inline .tox-editor-header{border:none;}
- .tox:not([dir=rtl]) .tox-toolbar__group:not(:last-of-type){border:none;}
- .tox:not([dir=rtl]) .tox-toolbar__group:not(:last-of-type):after{border:none;}
- .box {padding: 0 10px;width: 1000px;margin: 60px 0 20px;background-color: #ffffff;box-shadow: 0px 4px 8px 0px rgba(191, 191, 191, 0.6);}
- .tit{padding-bottom:10px;}
- .tit input{font-size:34px;font-weight: bold; padding:8px 8px;width:100%;box-sizing:border-box;border:none;box-shadow:none;background-color:#fefefe;color:#333333;border-bottom:1px dotted #ccc;outline: none;}
- .doc-cnt{min-height:1000px;overflow:auto;font-size:16px;padding:0.5em;}
- .doc-cnt:focus{outline:0;}
- .doc-cnt p{text-indent:0;}
- .tinymce-box:deep(.tox-fullscreen) {
- z-index: 10000;
- }
- .editor-custom-btn-container {
- position: absolute;
- right: 4px;
- top: 44px;
- z-index: 5;
- }
- .tox-fullscreen .editor-custom-btn-container {
- z-index: 10000;
- position: fixed;
- }
- .editor-upload-btn {
- display: inline-block;
- }
- .mytoolbar {
- background-color: #ffffff;
- position: fixed;
- padding-left: calc(50vw - 600px);
- left: 0;
- //transform: translateX(-50%);
- z-index: 10;
- width: 100%;
- box-shadow: 0px 4px 8px 0px rgba(191, 191, 191, 0.6);
- }
- </style>
- <style>
- .tox .tox-dialog__body-nav .tox-dialog__body-nav-item:nth-child(3) {
- display: none!important;
- }
- .tox-tinymce-inline .tox-editor-header {
- border: none;
- }
- .mytoolbar .tox-tinymce-inline .tox-editor-header {
- border: none;
- /*border-bottom: 1px solid #ccc;*/
- }
- .tox-tinymce-inline .tox-editor-header {
- border: none;
- }
- .tox-notifications-container {
- display: none;
- }
- </style>
|