目录
简介
本文就是对于tinymce在vue3中的组件化封装进行的总结,便于大家直接上手使用
作者环境配置
大环境
node 16.9.0
package.json配置
“dependencies”: {
“@element-plus/icons-vue”: “^2.0.6”,
“@tinymce/tinymce-vue”: “^5.0.0”,
“Base64”: “^1.1.0”,
“axios”: “^0.27.2”,
“element-plus”: “^2.2.12”,
“normalize.css”: “8.0.1”,
“path-browserify”: “^1.0.1”,
“pinia”: “^2.0.17”,
“pinia-plugin-persistedstate”: “^2.1.0”,
“qs”: “^6.11.0”,
“tinymce”: “5.10.0”,
“vue”: “^3.2.37”,
“vue-router”: “^4.1.3”,
“vue-schart”: “^2.0.0”
},
“devDependencies”: {
“@babel/core”: “^7.18.10”,
“@babel/eslint-parser”: “^7.18.9”,
“@vitejs/plugin-vue”: “^3.0.1”,
“@vue/compiler-sfc”: “^3.2.37”,
“@vue/eslint-config-prettier”: “^7.0.0”,
“autoprefixer”: “^10.4.8”,
“eslint”: “^8.21.0”,
“eslint-plugin-vue”: “^9.3.0”,
“postcss”: “^8.4.14”,
“prettier”: “^2.7.1”,
“sass”: “^1.54.1”,
“tailwindcss”: “^3.1.7”,
“vite”: “3.0.4”
},
本文相关环境或依赖版本
node 16.9.0
@tinymce/tinymce-vue 5.0.0
tinymce 5.10.0
环境注意项:
tinymce 4版本以下是vue2.0使用,6版本作者开发时不好用,原因不明
组件目录结构
|----------
|–index 主组件入口
|–sideEffects 副作用文件,所有副作用通过此文件进行引入
|–init 初始化文件,默认初始化配置在此文件处理
组件暴露emit或prop
v-modex:富文本输入内容
props:
disabled:禁用状态
plugins:插件 默认配置在init: 'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
toolbar:工具栏 默认配置在init: 'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs'
height:高度,默认配置在init:500
前置条件
- 安完依赖后,需要进入tinymce
依赖(node_modules\tinymce),将依赖内的文件复制到public文件夹内,作者是将相关文件放入public\lib\tinymce 文件夹内,此处根据实际变更init.js代码内容 - 中文需要去官网下载语言包,下载后和public文件夹内的tinymce放一起即可,同样根据实际变更init.js代码内容
组件代码
index.vue
<!--
* @Author: 计算机名不透露\用户名不透露 邮箱不透露
* @Date: 2022-08-15 13:07:35
* @LastEditors: 计算机名不透露\用户名不透露 邮箱不透露
* @LastEditTime: 2022-08-17 08:49:27
* @FilePath: \项目名不透露\src\components\Editor\index.vue
* @Description: 富文本编辑器主组件 =>tinymce组件封装
|----------
|--index 主组件入口
|--sideEffects 副作用文件,所有副作用通过此文件进行引入
|--init 初始化文件,默认初始化配置在此文件处理
图片上传均通过uploadAPI接口进行上传
v-modex:富文本输入内容
props:
disabled:禁用状态
plugins:插件 默认配置在init: 'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
toolbar:工具栏 默认配置在init: 'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs'
height:高度,默认配置在init:500
store:useBaseDataStore 基础数据:获取minioServerURL服务地址
-->
<template>
<TEditor v-model="content" :init="init" tag-name="div" :disabled="disabled" />
</template>
<script setup>
//引入tinymce编辑器
import TEditor from '@tinymce/tinymce-vue'
//引入方式引入node_modules里的tinymce相关文件文件
import tinymce from 'tinymce/tinymce' //tinymce默认hidden,不引入则不显示编辑器
import { computed } from 'vue-demi'
import './sideEffects'
import defaultInit from './init'
import { uploadAPI } from '@/api/base'
import { useBaseDataStore } from '@/store/baseData'
const baseDataStore = useBaseDataStore()
let minioServerURL = ''
baseDataStore.getMinioServer().then((res) => {
minioServerURL = res
})
const props = defineProps({
modelValue: {
type: String,
default: ''
},
disabled: Boolean,
plugins: [String, Array],
toolbar: [String, Array],
height: Number
})
const emit = defineEmits(['update:modelValue'])
const init = computed(() => {
const plugins = props.plugins || defaultInit.plugins
const toolbar = props.plugins || defaultInit.toolbar
const height = props.plugins || defaultInit.height
return {
...defaultInit,
plugins,
toolbar,
height,
images_upload_handler: (blobInfo, success, failure) => {
uploadGetUrl(blobInfo.blob(), success, failure)
},
file_picker_callback: (callback, value, meta) => {
console.log('file_picker_callback', callback, value, meta)
}
}
})
tinymce.init
const content = computed({
get() {
return props.modelValue
},
set(val) {
emit('update:modelValue', val)
}
})
/**
* @description: 上传图片事件,通过formData携带文件上传给业务接口
* @param {*} blob 图片blob对象
* @param {*} success 成功事件回调,接收url
* @param {*} failure 失败事件回调
* @return {*}
*/
function uploadGetUrl(blob, success, failure) {
const formData = new FormData() //
formData.append('file', blob)
uploadAPI(formData)
.then((res) => {
success(minioServerURL + res.content)
})
.catch((e) => {
failure(e)
})
}
</script>
因业务需要
- 有store 为获取服务地址的相关处理,因根据各公司实际设计不同而不同,故不暴露该文件做参考
- 图片上传需要经过images_upload_handler将图片上传给uploadAPI接口,此处可以根据各位业务配置进行修改uploadGetUrl接口
init.js
/*
* @Author: DESKTOP-NRAJN91\14382 00000000@qq.com
* @Date: 2022-08-15 16:22:32
* @LastEditors: DESKTOP-NRAJN91\14382 00000000@qq.com
* @LastEditTime: 2022-08-15 18:06:57
* @FilePath: \LNZhiAn\src\components\Editor\init.js
* @Description: tinymce 富文本默认配置
*/
const defaultInit = {
language_url: '/lib/tinymce/langs/zh_CN.js', //引入语言包文件
language: 'zh_CN', //语言类型
skin_url: '/lib/tinymce/skins/ui/oxide', //皮肤:浅色
// skin_url: '/lib/tinymce/skins/ui/oxide-dark',//皮肤:暗色
plugins:
'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
toolbar:
'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
styleselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs', //工具栏配置,设为false则隐藏
toolbar_mode: 'sliding',
// menubar: 'file edit insert view format table tools', //菜单栏配置,设为false则隐藏,不配置则默认显示全部菜单,也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
menu: {
// file: { title: '文件', items: 'newdocument' },
edit: { title: '编辑', items: 'undo redo | cut copy paste pastetext | selectall' },
insert: { title: '插入', items: 'link image | hr' },
view: { title: '查看', items: 'visualaid' }
// format: {
// title: '格式',
// items:
// 'bold italic underline strikethrough superscript subscript | formats | removeformat',
// },
// table: { title: '表格', items: 'inserttable tableprops deletetable | cell row column' },
// tools: { title: '工具', items: 'spellchecker code' },
},
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小
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;',
height: 500, //注:引入autoresize插件时,此属性失效
placeholder: '在这里输入文字',
branding: false, //tiny技术支持信息是否显示
resize: false, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
statusbar: false, //最下方的元素路径和字数统计那一栏是否显示
elementpath: false, //元素路径是否显示
content_style: 'img {max-width:100%;}' //直接自定义可编辑区域的css样式
// content_css: '/tinycontent.css', //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
}
export default defaultInit
tinymce 富文本默认配置文件,因作者认为,此处无需暴露给业务,且功能单一,故单立文件便于维护
可参考TinyMCE中文文档中文手册
sideEffects.js
/*
* @Author: DESKTOP-NRAJN91\14382 00000000@qq.com
* @Date: 2022-08-15 16:48:06
* @LastEditors: DESKTOP-NRAJN91\14382 00000000@qq.com
* @LastEditTime: 2022-08-15 17:09:14
* @FilePath: \LNZhiAn\src\components\TEditor\sideEffects.js
* @Description: tinymce 副作用引入
*/
import 'tinymce/themes/silver' //编辑器主题,不引入则报错
import 'tinymce/icons/default' //引入编辑器图标icon,不引入则不显示对应图标
// 引入编辑器插件
import 'tinymce/plugins/advlist' //高级列表
import 'tinymce/plugins/anchor' //锚点
import 'tinymce/plugins/autolink' //自动链接
import 'tinymce/plugins/autoresize' //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效
import 'tinymce/plugins/autosave' //自动存稿
import 'tinymce/plugins/charmap' //特殊字符
import 'tinymce/plugins/code' //编辑源码
import 'tinymce/plugins/codesample' //代码示例
import 'tinymce/plugins/directionality' //文字方向
import 'tinymce/plugins/emoticons' //表情
import 'tinymce/plugins/fullpage' //文档属性
import 'tinymce/plugins/fullscreen' //全屏
import 'tinymce/plugins/help' //帮助
import 'tinymce/plugins/hr' //水平分割线
import 'tinymce/plugins/image' //插入编辑图片
import 'tinymce/plugins/importcss' //引入css
import 'tinymce/plugins/insertdatetime' //插入日期时间
import 'tinymce/plugins/link' //超链接
import 'tinymce/plugins/lists' //列表插件
import 'tinymce/plugins/media' //插入编辑媒体
import 'tinymce/plugins/nonbreaking' //插入不间断空格
import 'tinymce/plugins/pagebreak' //插入分页符
import 'tinymce/plugins/paste' //粘贴插件
import 'tinymce/plugins/preview' //预览
import 'tinymce/plugins/print' //打印
import 'tinymce/plugins/quickbars' //快速工具栏
import 'tinymce/plugins/save' //保存
import 'tinymce/plugins/searchreplace' //查找替换
import 'tinymce/plugins/spellchecker' //拼写检查,暂未加入汉化,不建议使用
import 'tinymce/plugins/tabfocus' //切入切出,按tab键切出编辑器,切入页面其他输入框中
import 'tinymce/plugins/table' //表格
import 'tinymce/plugins/template' //内容模板
import 'tinymce/plugins/textcolor' //文字颜色
import 'tinymce/plugins/textpattern' //快速排版
import 'tinymce/plugins/toc' //目录生成器
import 'tinymce/plugins/visualblocks' //显示元素范围
import 'tinymce/plugins/visualchars' //显示不可见字符
import 'tinymce/plugins/wordcount' //字数统计
副作用文件,太长了且与业务弱关联,单立文件便于维护