开发环境
1. vscode
开发语言
1. vue
2. javaScript
插件安装
1. npm install tinymce -S
2. 可以使用里面的文件, 下载后可以在node_modules 里面查看如下未目录结构
3. 可以将整个结构拷在static里面,为了节省打包后的文件大小可以将tinymce.min.js以cdn方式导入放在index.html中<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.5/tinymce.min.js"></script>
4. 附上封装的代码可以直接导入使用<template>
<div>
<textarea :id="Id"></textarea>
</div>
</template>
<script>
import "tinymce/langs/zh_CN.js"; // 引入中文包地址
// import axios from "axios"; // 可导入axios文件进行上传图片
export default {
data() {
const Id = Date.now();
return {Id: Id, // 构造tinymce的选择器Editor: null,tinymceConfig: {// GLOBALheight: 500,theme: "modern",menubar: false,toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat hr | paste code link | undo redo | fullscreen `,plugins: `pasteimportcssimagecodetableadvlistfullscreenlinkmedialiststextcolorcolorpickerhrpreview`,// CONFIGforced_root_block: "p",force_p_newlines: true,importcss_append: true,skin_url: "/static/tinymce/skins/lightgray", // 可以把node_modules 下面的文件导入到static然后引入到这里language_url: "/static/tinymce/langs/zh_CN.js", // 导入中文包language: "zh_CN",// 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: Pastepaste_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: Fontfontsize_formats: "10px 11px 12px 14px 16px 18px 20px 24px",// CONFIG: StyleSelectstyle_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" }]}],// FontSelectfont_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`,// Tabtabfocus_elements: ":prev,:next",object_resizing: true,// Imageimagetools_toolbar:"rotateleft rotateright | flipv fliph | editimage imageoptions"}
};
},
props: {
value: {default: "",type: String
},
config: {type: Object,default: () => {return {theme: "modern",height: 300};}
},
// 该参数就是上传文件的url
url: {default: "",type: String
},
//上传文件类型
accept: {default: "image/jpeg, image/png, image/jpg,",type: String
},
maxSize: {default: 2097152,type: Number
},
withCredentials: {default: false,type: Boolean
}
},
mounted() {
this.init();
},
beforeDestroy() {
// 销毁tinymce
// window.tinymce.remove(`$#{this.Id}`)
},
methods: {
init() {const self = this;this.Editor = window.tinymce.init({// 默认配置...this.tinymceConfig,// 图片上传images_upload_handler: function(blobInfo, success, failure, progress) {if (blobInfo.blob().size > self.maxSize) {failure("文件体积过大");}if (self.accept.indexOf(blobInfo.blob().type) > -1) {uploadPic();} else {failure("图片格式错误");}function uploadPic() {// 用axios 上传文件// progress(0);// let param = new FormData();// let config = {// headers: {// "Content-Type": "multipart/form-data"// }// };// param.append("file", blobInfo.blob());// console.log('axios', axios);// axios// .post("http://operate-dev.winchaingroup.com/api/upload", param, config)// .then(response => {// success(response.data.data);// self.$emit("on-upload-complete", [json, success, failure]);// progress(100);// })// .catch(error => {// console.log("err", error);// });// 用ajax上传文件const xhr = new XMLHttpRequest();let createFrom = document.createElement("form");let FromData = new FormData(createFrom);xhr.withCredentials = self.withCredentials;xhr.open("POST", self.url);xhr.onload = function() {if (xhr.status !== 200) {// 抛出 'on-upload-fail' 钩子failure("上传失败: " + xhr.status);return;}const json = JSON.parse(xhr.responseText);// success函数中的参数就是你上传文件返回的urlsuccess(json.data);progress(100);// 抛出 'on-upload-complete' 钩子};FromData.append("file", blobInfo.blob());xhr.send(FromData);}},// prop内传入的的config...this.config,// 挂载的DOM对象selector: `#${this.Id}`,setup: editor => {// 抛出 'on-ready' 事件钩子editor.on("init", () => {self.loading = false;editor.setContent(self.value);});// 抛出 'input' 事件钩子,同步value数据editor.on("input change undo redo", () => {});}});
}
}
};
</script>
5. 在组件中导入即可使用import tinymce from './tinymce/index'
引用
https://www.bootcdn.cn/tinymce/ // tinymce地址