富文本编辑器 Vue3 Tinymce
- 使用yarn 或 npm 安装: "tinymce": "^6.1.2" 和 "@tinymce/tinymce-vue": "4"
- public 文件夹下新建 tinymce:
- skins 从 node_modules/tinymce 中复制
- langs 下载:https://files.cnblogs.com/files/kitty-blog/zh-Hans.js?t=1662694691 我也是从官网上下载的,可以放心使用!
- 在 components 文件中新建文件 TinymceEditor/index.vue
- 在需要的页面的script中引入:我使用的是setup语法糖 :
import TEditor from '@/components/TinymceEditor'
- 在页面的template 中引入
<TEditor ref="editor" :value="form.content" @input="changeContent"/>
- form.content 输入的内容
- changeContent 方法,接受最新的内容并更新form.content
TinymceEditor/index.vue 组件代码如下
1 <template> 2 <div class="tinymce-box"> 3 <Editor v-model="contentValue" :init="init" :disabled="disabled" @onClick="onClick" /> 4 </div> 5 </template> 6 7 <script setup name='TEditor'> 8 import {uploadSingleFile} from '@/api/upload.js' 9 //引入tinymce编辑器 10 import Editor from '@tinymce/tinymce-vue' 11 12 //引入node_modules里的tinymce相关文件文件 13 import tinymce from 'tinymce/tinymce' //tinymce默认hidden,不引入则不显示编辑器 14 import 'tinymce/themes/silver' //编辑器主题,不引入则报错 15 import 'tinymce/icons/default' //引入编辑器图标icon,不引入则不显示对应图标 16 17 // 引入编辑器插件(基本免费插件都在这儿了) 18 import 'tinymce/models/dom' 19 import 'tinymce/plugins/advlist' //高级列表 20 import 'tinymce/plugins/anchor' //锚点 21 import 'tinymce/plugins/autolink' //自动链接 22 import 'tinymce/plugins/autoresize' //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效 23 import 'tinymce/plugins/autosave' //自动存稿 24 import 'tinymce/plugins/charmap' //特殊字符 25 import 'tinymce/plugins/code' //编辑源码 26 import 'tinymce/plugins/codesample' //代码示例 27 import 'tinymce/plugins/directionality' //文字方向 28 import 'tinymce/plugins/emoticons' //表情 29 import 'tinymce/plugins/fullscreen' //全屏 30 import 'tinymce/plugins/help' //帮助 31 import 'tinymce/plugins/image' //插入编辑图片 32 import 'tinymce/plugins/importcss' //引入css 33 import 'tinymce/plugins/insertdatetime' //插入日期时间 34 import 'tinymce/plugins/link' //超链接 35 import 'tinymce/plugins/lists' //列表插件 36 import 'tinymce/plugins/media' //插入编辑媒体 37 import 'tinymce/plugins/nonbreaking' //插入不间断空格 38 import 'tinymce/plugins/pagebreak' //插入分页符 39 import 'tinymce/plugins/preview'//预览 40 // import 'tinymce/plugins/quickbars' //快速工具栏 41 import 'tinymce/plugins/save' //保存 42 import 'tinymce/plugins/searchreplace' //查找替换 43 import 'tinymce/plugins/table' //表格 44 // import 'tinymce/plugins/template' //内容模板 45 import 'tinymce/plugins/visualblocks' //显示元素范围 46 import 'tinymce/plugins/visualchars' //显示不可见字符 47 import 'tinymce/plugins/wordcount' //字数统计 48 const props = defineProps({ 49 value: { 50 type: String, 51 default: '' 52 }, 53 disabled: { 54 type: Boolean, 55 default: false 56 }, 57 plugins: { 58 type: [String, Array], 59 default: 'preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media code codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave ' 60 }, 61 toolbar: { 62 type: [String, Array], 63 default: 'fullscreen undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \ 64 styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \ 65 table image media charmap hr pagebreak insertdatetime preview | code selectall searchreplace visualblocks | indent2em lineheight formatpainter axupimgs' 66 }, 67 }) 68 const init = ref({ 69 language_url: window.location.origin + '/tinymce/langs/zh-Hans.js', //引入语言包文件 70 language: 'zh-Hans', //语言类型 71 directionality : 'ltr', 72 skin_url: window.location.origin + '/tinymce/skins/ui/oxide', //皮肤:浅色 73 // skin_url: '/tinymce/skins/ui/oxide-dark',//皮肤:暗色 74 content_css: window.location.origin + '/tinymce/skins/ui/oxide/content.css', 75 plugins: props.plugins, //插件配置 76 toolbar: props.toolbar, //工具栏配置,设为false则隐藏 77 // menubar: 'file edit', //菜单栏配置,设为false则隐藏,则默认显示全部菜单不配置,也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单” 78 79 fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小 80 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;', //字体样式 81 lineheight_formats: "0.5 0.8 1 1.2 1.5 1.75 2 2.5 3 4 5", //行高配置,也可配置成"12px 14px 16px 20px"这种形式 82 83 height: 600, //注:引入autoresize插件时,此属性失效 84 placeholder: '在这里输入正文内容', 85 branding: false, //tiny技术支持信息是否显示 86 resize: false, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号 87 // statusbar: false, //最下方的元素路径和字数统计那一栏是否显示 88 elementpath: false, //元素路径是否显示 89 90 content_style: "img {max-width:100%;}", //直接自定义可编辑区域的css样式 91 // content_css: '/tinycontent.css', //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入 92 93 // images_upload_url: '/apib/api-upload/uploadimg', //后端处理程序的url,建议直接自定义上传函数image_upload_handler,这个就可以不用了 94 // images_upload_base_path: '/demo', //相对基本路径--关于图片上传建议查看--http://tinymce.ax-z.cn/general/upload-images.php 95 paste_data_images: true, //图片是否可粘贴 96 images_upload_handler: (blobInfo, success, failure) => { 97 if(blobInfo.blob().size/1024/1024>2){ 98 failure("上传失败,图片大小请控制在 2M 以内") 99 }else{ 100 let params=new FormData() 101 params.append('file',blobInfo.blob()) 102 uploadSingleFile(params).then(res=>{ 103 if(res.code==200){ 104 success(res.data.url) //上传成功,在成功函数里填入图片路径 105 }else{ 106 failure("上传失败") 107 } 108 }).catch(()=>{ 109 failure("上传出错,服务器开小差了呢") 110 }) 111 } 112 }, 113 file_picker_callback: (callback, value, meta) => { 114 //文件分类 115 var filetype='.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'; 116 //为不同插件指定文件类型 117 switch(meta.filetype){ 118 case 'image': 119 filetype='.jpg, .jpeg, .png, .gif'; 120 break; 121 case 'media': 122 filetype='.mp3, .mp4'; 123 break; 124 case 'file': 125 default: 126 } 127 //模拟出一个input用于添加本地文件 128 var input = document.createElement('input'); 129 input.setAttribute('type', 'file'); 130 input.setAttribute('accept', filetype); 131 input.click(); 132 input.onchange = function() { 133 var file = this.files[0]; 134 let params=new FormData() 135 params.append('file',file) 136 uploadSingleFile(params).then(res=>{ 137 if(res.code==200){ 138 callback(res.data.url, {text: '文件'}); 139 } 140 }).catch(()=>{ 141 failure("上传出错,服务器开小差了呢") 142 }) 143 } 144 } 145 }) 146 const contentValue = ref() 147 const emits = defineEmits(['input','onClick']) 148 watch(()=>props.value,(newVal,oldVal)=>{ 149 contentValue.value = newVal 150 },{ 151 deep:true, 152 immediate:true 153 }) 154 watch(()=>contentValue.value,(newContentVal,oldContentVal)=>{ 155 emits('input', newContentVal) 156 },{ 157 deep:true, 158 immediate:true 159 }) 160 onMounted(()=>{ 161 tinymce.init({}) 162 }) 163 const onClick =(e)=>{ 164 emits('onClick', e, tinymce) 165 } 166 //清空内容 167 const clear =()=>{ 168 contentValue.value = '' 169 } 170 </script> 171 172 <style lang="scss"> 173 174 </style>
作者:胡倩倩0903
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
posted on 2022-09-09 11:40 kitty20180903suzhou 阅读(979) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY