|
@@ -0,0 +1,143 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <Editor v-model="content" :init="myTinyInit"></Editor>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import {computed, defineEmits, defineProps, onMounted, reactive, ref, watch} from 'vue'
|
|
|
+import tinymce from "tinymce/tinymce";
|
|
|
+import Editor from '@tinymce/tinymce-vue';
|
|
|
+import "tinymce/icons/default/icons";
|
|
|
+import "tinymce/themes/silver";
|
|
|
+import "tinymce/models/dom/model";
|
|
|
+
|
|
|
+//按需引入插件
|
|
|
+// import "tinymce/plugins/image";
|
|
|
+// import "tinymce/plugins/table";
|
|
|
+// import "tinymce/plugins/lists";
|
|
|
+// import "tinymce/plugins/link";
|
|
|
+// import "tinymce/plugins/help";
|
|
|
+// import "tinymce/plugins/wordcount";
|
|
|
+
|
|
|
+import 'tinymce/models/dom'; // 引入dom模块。从 Tinymce6,开始必须有此模块导入
|
|
|
+import 'tinymce/skins/ui/oxide/skin.css'//样式
|
|
|
+import 'tinymce/themes/silver'; //默认主题
|
|
|
+// import 'tinymce/icons/default'; //引入编辑器图标icon,不引入则不显示对应图标
|
|
|
+// import 'tinymce/langs/zh-Hans'; //引入编辑器语言包
|
|
|
+// import '/tinymce/langs/zh-CN'; //引入编辑器语言包
|
|
|
+// import 'tinymce/models/dom'; // 引入dom模块。从 Tinymce6,开始必须有此模块导入
|
|
|
+// 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/fullscreen'; //全屏
|
|
|
+import 'tinymce/plugins/help'; //帮助
|
|
|
+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/preview'; //预览
|
|
|
+import 'tinymce/plugins/quickbars'; //快速工具栏
|
|
|
+import 'tinymce/plugins/save'; //保存
|
|
|
+import 'tinymce/plugins/searchreplace'; //查找替换
|
|
|
+import 'tinymce/plugins/table'; //表格
|
|
|
+// import 'tinymce/plugins/template'; //内容模板
|
|
|
+import 'tinymce/plugins/visualblocks'; //显示元素范围
|
|
|
+import 'tinymce/plugins/visualchars'; //显示不可见字符
|
|
|
+import 'tinymce/plugins/wordcount'; //字数统计
|
|
|
+
|
|
|
+import axios from "axios";
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ modelValue: {
|
|
|
+ type: String,
|
|
|
+ default: ""
|
|
|
+ },
|
|
|
+ plugins: {
|
|
|
+ type: [String, Array],
|
|
|
+ // default:'lists link image table help wordcount',
|
|
|
+ default:'codesample preview searchreplace autolink directionality visualblocks visualchars image link template table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave help'
|
|
|
+ },
|
|
|
+ toolbar: {
|
|
|
+ type: [String, Array],
|
|
|
+ default: `undo redo formatselect bold italic alignjustify bullist numlist outdent indent help preview codesample code backcolor styles directionality fontfamily fontsize searchreplace image link alignleft aligncenter alignright template table charmap pagebreak nonbreaking anchor
|
|
|
+ insertdatetime advlist lists wordcount autosave `,
|
|
|
+ }
|
|
|
+});
|
|
|
+const emit = defineEmits(['input']);
|
|
|
+const piniaToken = JSON.parse(localStorage.getItem('pinia-token') || '')
|
|
|
+const myTinyInit = reactive({
|
|
|
+ width: '100%',
|
|
|
+ height: 500,
|
|
|
+ branding: true,
|
|
|
+ menubar: true,
|
|
|
+ resize: true,
|
|
|
+ promotion: false, //Upgrade是否开启
|
|
|
+ branding: false, //tiny技术支持信息是否显示
|
|
|
+ language_url: "/tinymce/langs/zh_CN.js", // 语言包的路径,具体路径看自己的项目
|
|
|
+ language: "zh_CN",
|
|
|
+ skin_url: "/tinymce/skins/ui/oxide", //手动引入
|
|
|
+ content_css: '/tinymce/skins/content/default/content.css', //手动引入
|
|
|
+ toolbar_mode: "wrap",
|
|
|
+ plugins: props.plugins,
|
|
|
+ toolbar: props.toolbar,
|
|
|
+ line_height_formats: '1 1.2 1.4 1.6 2', //行高
|
|
|
+ font_size_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小
|
|
|
+ font_family_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;',
|
|
|
+ //图片上传方法(注意!!:要使用 promise 对象中的 resolve 返回图片路径,否则会报错)
|
|
|
+ images_upload_handler: (blobInfo) => new Promise((resolve, reject) => {
|
|
|
+ let formData = new FormData();
|
|
|
+ console.log(blobInfo, '<==== blobInfo')
|
|
|
+ formData.append('multipartFile', blobInfo.blob(), blobInfo.filename());
|
|
|
+ axios.post(`/api/common/uploadFile`, formData, {
|
|
|
+ headers: ({
|
|
|
+ 'Content-Type': 'multipart/form-data',
|
|
|
+ // 'Authorization': "Bearer " + piniaToken.token
|
|
|
+ 'Authorization': piniaToken.token
|
|
|
+ })
|
|
|
+ }).then(res => {
|
|
|
+ if(res.data.code == 0) {
|
|
|
+ resolve(`${res.data.data}`)
|
|
|
+ } else {
|
|
|
+ ElMessage.warning('上传失败')
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ reject(error);
|
|
|
+ })
|
|
|
+ }),
|
|
|
+});
|
|
|
+
|
|
|
+
|
|
|
+const initContent = computed(() => {
|
|
|
+ return props.modelValue
|
|
|
+});
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ tinymce.init({});
|
|
|
+})
|
|
|
+
|
|
|
+const content = ref();
|
|
|
+watch(initContent, (newVal) => {
|
|
|
+ content.value = newVal;
|
|
|
+}, {deep: true, immediate: true});
|
|
|
+
|
|
|
+watch(content, (newVal) => {
|
|
|
+ emit("input", newVal);
|
|
|
+}, {deep: true});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+</style>
|