花生壳盒子做网站服务器,济南建设网站的公司哪家好,宁波网站建设方案推广,兰州企业网站制作文章目录 前言遇到的坑插入上传图片插件上传图片请求与返回值处理本地文件引入报错解决源码 前言
如果你的前端项目技术栈使用的是Vue3nuxtts#xff0c;并且老大让你集成一下那个传说中非常丝滑的TinyMCE富文本编辑器#xff0c;那么恭喜你和我一样中大奖了。 网上找了好久… 文章目录 前言遇到的坑插入上传图片插件上传图片请求与返回值处理本地文件引入报错解决源码 前言
如果你的前端项目技术栈使用的是Vue3nuxtts并且老大让你集成一下那个传说中非常丝滑的TinyMCE富文本编辑器那么恭喜你和我一样中大奖了。 网上找了好久都没有找到同类型且靠谱的实现方案于是就自己着手研究文档并踩着坑解决了。 先贴一下由莫若卿大佬翻译的TinyMCE中文文档地址 TinyMCE中文文档中文手册 懒得看过程的直接跳到最下方复制组件源码后按自己项目微调即可
遇到的坑
按照文档把TinyMCE组件写好了引用到功能页上……哎我辣么大个富文本编辑器嘞 明明是按照和网上一模一样的方式引入的为什么编辑器不见了呢 来看一下控制台报错 是汉化文件和css文件引入失败可我的init参数和本地文件路径明明是正确的啊 既然init不行那就impot手动引入
import tinymce/langs/zh-Hans
import tinymce/skins/ui/oxide/skin.min.css
import tinymce/skins/ui/oxide/content.min.css
import tinymce/skins/content/default/content.css
// PS网上说这些是必须写的否则富文本显示不出来其实是不对的这里根本不需要手动引入我们后续来说原因手动引入后富文本编辑框正常显示了但控制台还是会报相同的错而且中文化文件也没生效。 插入上传图片插件
如果是偷工减料得过且过的摸鱼仔做到这里就能交差了这下巧了那不就是我么~雾
但是嘞还缺了一个很重要的东西那就是图片上传按钮啊 这个简单把image加到toolbar里就行了呗于是我左加右加这磨人的小按钮就是不出来啊T_T
情急之下决定去好好研究文档了才发现需要image需要先在plugins里声明引入才行 plugins: {type: [String, Array],default: lists table image}, //必填toolbar: {type: [String, Array],default: codesample bold italic underline alignleft aligncenter alignright alignjustify image | undo redo | formatselect | fontselect | fontsizeselect | forecolor backcolor | bullist numlist outdent indent | lists link table code | removeformat } //必填上传图片请求与返回值处理
然后我们开启文件上传的微服务后来测试一下我去这返回的是什么东西 原来是图片上传接口的返回值处理有问题那就改一下CV下来的方法呗 //图片上传custom_images_upload: true,images_upload_handler: (blobInfo, progress) new Promise((resolve, reject) {if (blobInfo.blob().size / 1024 / 1024 2) {reject({ message: 上传失败图片大小请控制在 2M 以内, remove: true })return} else {const ph import.meta.env.VITE_BASE_PATH : import.meta.env.VITE_SERVER_PORT /let params new FormData()params.append(file, blobInfo.blob())let config {headers: {Content-Type: multipart/form-data}}axios.post(/api/file/upload, params, config) // 第一个参数是请求url因为是demo就随便写了项目中记得拼接环境变量.then(res {if (res.data.code 200) {console.log(res)// resolve(ph res.data.msg) // 注意看返回值的结构因为少写一层data找了几分钟resolve(res.data.data.url) //上传成功在成功函数里填入图片路径} else {reject(HTTP Error: 上传失败 res.data.code)return}}).catch(() {reject(上传出错服务器开小差了呢)return})}}),图片上传终于弄成功了蚌埠住了捏 本地文件引入报错解决
emmm既然都弄到这了就把页面报错的bug也解决了呗
再看一眼报错引用本地文件路径好像也没错啊 等等……好像有什么不对劲原来是你nuxt
由于nuxt配置的原因本地资源引入路径要加个/_nuxt前缀之前也被坑过……
那就正好按照TinyMCE文档上写的统一规定一个base_url好了 这样一来手动import引入的那几行就可以删掉了再搞个暗夜皮肤帅 base_url: /_nuxt/assets/tinymce,language: zh-Hans, //语言skin: oxide-dark, // 暗夜皮肤// language_url: /_nuxt/assets/tinymce/langs/zh-Hans.js, // 语言包的路径具体路径看自己的项目文档后面附上中文js文件// skin_url: /_nuxt/assets/tinymce/skins/ui/oxide, // skin路径具体路径看自己的项目中文化也正常显示了
至此大功告成~ 源码
TEditor.client.vue组件
html
templateeditor :idtinymceId v-modelmyValue :initinit :disableddisabled/editor
/templatejs
script setup langts
import Editor from tinymce/tinymce-vue//JS部分
//在js中引入所需的主题和组件
import tinymce from tinymce/tinymce
import tinymce/skins/content/default/content.css
import tinymce/themes/silver
import tinymce/themes/silver/theme
// import tinymce/langs/zh-Hans.js
import tinymce/icons/default //引入编辑器图标icon不引入则不显示对应图标
import tinymce/models/dom // 这里是个坑 一定要引入//在TinyMce.vue中接着引入相关插件
import tinymce/icons/default/icons
import tinymce/plugins/image // 插入上传图片插件
import tinymce/plugins/media // 插入视频插件
import tinymce/plugins/table // 插入表格插件
import tinymce/plugins/lists // 列表插件
import tinymce/plugins/wordcount // 字数统计插件
import tinymce/plugins/code // 源码
// import tinymce/langs/zh-Hans // 中文
// import tinymce/skins/ui/oxide/skin.min.css
// import tinymce/skins/ui/oxide/content.min.css
// import tinymce/skins/content/default/content.css
// import tinymce/plugins/fullscreen //全屏//接下来定义编辑器所需要的插件数据
import { reactive, ref } from vue
import { onMounted, defineEmits, watch } from vue
import axios from axios
// import { updateImg } from /api/order/order
const emits defineEmits([getContent])
//这里我选择将数据定义在props里面方便在不同的页面也可以配置出不同的编辑器当然也可以直接在组件中直接定义
const props defineProps({value: {type: String,default: () {return }},baseUrl: {type: String,default: },disabled: {type: Boolean,default: false},plugins: {type: [String, Array],default: lists table image}, //必填toolbar: {type: [String, Array],default: codesample bold italic underline alignleft aligncenter alignright alignjustify image | undo redo | formatselect | fontselect | fontsizeselect | forecolor backcolor | bullist numlist outdent indent | lists link table code | removeformat } //必填
})
//用于接收外部传递进来的富文本
const myValue ref(props.value)
const tinymceId ref(vue-tinymce- new Date() ((Math.random() * 1000).toFixed(0) ))
//定义一个对象 init初始化
const init ref({selector: # tinymceId.value, //富文本编辑器的id,// language_url: /_nuxt/assets/tinymce/langs/zh-Hans.js, // 语言包的路径具体路径看自己的项目文档后面附上中文js文件base_url: /_nuxt/assets/tinymce,language: zh-Hans, //语言skin: oxide-dark, // 暗夜皮肤// skin_url: /_nuxt/assets/tinymce/skins/ui/oxide, // skin路径具体路径看自己的项目height: 400, //编辑器高度branding: false, //是否禁用“Powered by TinyMCE”menubar: true, //顶部菜单栏显示image_dimensions: false, //去除宽高属性plugins: props.plugins, //这里的数据是在props里面就定义好了的toolbar: props.toolbar, //这里的数据是在props里面就定义好了的font_formats: Arialarial,helvetica,sans-serif; 宋体SimSun; 微软雅黑Microsoft Yahei; Impactimpact,chicago;, //字体fontsize_formats: 11px 12px 14px 16px 18px 24px 36px 48px 64px 72px, //文字大小// 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,file_picker_types: file,content_css: /_nuxt/assets/tinymce/skins/content/default/content.css, //以css文件方式自定义可编辑区域的css样式css文件需自己创建并引入//图片上传custom_images_upload: true,images_upload_handler: (blobInfo, progress) new Promise((resolve, reject) {if (blobInfo.blob().size / 1024 / 1024 2) {reject({ message: 上传失败图片大小请控制在 2M 以内, remove: true })return} else {const ph import.meta.env.VITE_BASE_PATH : import.meta.env.VITE_SERVER_PORT /let params new FormData()params.append(file, blobInfo.blob())let config {headers: {Content-Type: multipart/form-data}}axios.post(/api/file/upload, params, config) // 第一个参数是请求url因为是demo就随便写了项目中记得拼接环境变量.then(res {if (res.data.code 200) {console.log(res)// resolve(ph res.data.msg) // 注意看返回值的结构因为少写一层data找了几分钟resolve(res.data.data.url) //上传成功在成功函数里填入图片路径} else {reject(HTTP Error: 上传失败 res.data.code)return}}).catch(() {reject(上传出错服务器开小差了呢)return})}}),// 文件上传file_picker_callback: (callback, value, meta) {// Provide file and text for the link dialogif (meta.filetype file) {callback(mypage.html, { text: My text })}// Provide image and alt text for the image dialogif (meta.filetype image) {callback(myimage.jpg, { alt: My alt text })}// Provide alternative source and posted for the media dialogif (meta.filetype media) {callback(movie.mp4, { source2: alt.ogg, poster: image.jpg })}}
})
//监听外部传递进来的的数据变化
watch(() props.value,() {myValue.value props.valueemits(getContent, myValue.value)}
)
//监听富文本中的数据变化
watch(() myValue.value,() {emits(getContent, myValue.value)}
)
//在onMounted中初始化编辑器
onMounted(() {tinymce.init({})
})
/script 若对您有帮助请麻烦给我的cloud-demo开源项目点个星哦~该组件在项目中也用到了感兴趣的话可以拉下来玩一玩THX 项目仓库https://gitee.com/Yuzaki-Nasa/nasa-cloud-vue3-travel-demo NASA-cloud-Vue3-travelDemo