Vue3中使用tinymce全功能演示,包括开源功能

news2024/11/18 22:48:18

效果图:

1、下载插件:

npm i tinymce
npm i @tinymce/tinymce-vue

2、在node_modules文件夹中找到tinymce下的skins复制到项目public文件夹中

    (可以先创建一个tinymce文件夹):

 

3、在tinymce官网中下载中文包,并放在刚刚创建的tinymce文件夹中

  • Language Packages | Trusted Rich Text Editor | TinyMCE   前往官网
  • 点击按钮下载全部语言包,解压放至tinymce文件夹
  • TinyMCE中文文档中文手册  中文文档给大家作参考

4、在项目中建立components/TEditor文件夹封装tinymce(注释比较全 涵盖90%的功能):

<template>
  <div>
    <editor
      v-model="myValue"
      :init="init"
      :disabled="disabled"
      :id="tinymceId"
    ></editor>
  </div>
</template>

<script setup>
import { uploadImg } from "@/api/article";
import tinymce from "tinymce/tinymce";
import "tinymce/skins/content/default/content.css";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/models/dom"; // 这里是个坑 一定要引入
import "tinymce/themes/silver"; // 界面UI主题
import "tinymce/plugins/image";
import "tinymce/plugins/table";
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/wordcount"; // 文字计数
import "tinymce/plugins/preview"; // 预览
import "tinymce/plugins/emoticons"; // emoji表情
import "tinymce/plugins/emoticons/js/emojis.js"; //必须引入这个文件才有表情图库
import "tinymce/plugins/code"; // 编辑源码
import "tinymce/plugins/link"; // 链接插件
import "tinymce/plugins/advlist"; //高级列表
import "tinymce/plugins/codesample"; //代码示例
import "tinymce/plugins/autoresize"; // 自动调整编辑器大小
import "tinymce/plugins/quickbars"; // 光标处快捷提示
import "tinymce/plugins/nonbreaking"; //插入不间断空格
import "tinymce/plugins/searchreplace"; //查找替换
import "tinymce/plugins/autolink"; //自动链接
import "tinymce/plugins/directionality"; //文字方向
import "tinymce/plugins/visualblocks"; //显示元素范围
import "tinymce/plugins/visualchars"; //显示不可见字符
import "tinymce/plugins/charmap"; // 特殊符号
import "tinymce/plugins/nonbreaking"; //插入不间断空格
import "tinymce/plugins/insertdatetime"; //插入日期时间
import "tinymce/plugins/importcss"; //引入自定义样式的css文件

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:
      "preview searchreplace autoresize quickbars autolink directionality code visualblocks visualchars image link codesample table nonbreaking charmap insertdatetime advlist lists wordcount emoticons",
  },
  knwlgId: {
    type: String,
  },
  toolbar: {
    type: [String, Array],
    default:
      "undo redo | forecolor backcolor bold emoticons italic underline strikethrough link codesample table image | alignleft aligncenter alignright alignjustify outdent indent | \
    blocks fontfamily fontsize | bullist numlist | blockquote subscript superscript removeformat | \
    charmap insertdatetime | cut copy paste pastetext",
  },
});

const loading = ref(false);
const myValue = ref(props.value);
const tinymceId = ref(
  "vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + "")
);

//定义一个对象 init初始化
const init = reactive({
  selector: "#" + tinymceId.value, //富文本编辑器的id,
  language_url: "../../../public/tinymce/langs/zh_CN.js", // 语言包的路径,具体路径看自己的项目
  language: "zh_CN",
  skin_url: "../../../public/tinymce/skins/ui/oxide", // skin路径,具体路径看自己的项目
  branding: false, // 是否禁用“Powered by TinyMCE”
  promotion: false, //去掉 upgrade
  menubar: "edit view insert format tools table",
  paste_data_images: true, //允许粘贴图像
  image_dimensions: false, //去除宽高属性
  plugins: props.plugins, //这里的数据是在props里面就定义好了的
  toolbar: props.toolbar, //这里的数据是在props里面就定义好了的
  // 选中图片的快捷提示
  quickbars_image_toolbar:
    "alignleft aligncenter alignright | rotateleft rotateright | imageoptions",
  editimage_toolbar:
    "rotateleft rotateright | flipv fliph | editimage imageoptions",
  // 文字样式
  font_formats:
    "Arial=arial,helvetica,sans-serif; 宋体=SimSun; 微软雅黑=Microsoft Yahei; Impact=impact,chicago;", //字体
  fontsize_formats: "11px 12px 14px 16px 18px 24px 36px 48px 64px 72px", //文字大小
  image_caption: true,
  editimage_cors_hosts: ["picsum.photos"],
  noneditable_class: "mceNonEditable",
  toolbar_mode: "wrap", // 工具栏模式 floating / sliding / scrolling / wrap
  // contextmenu: "bold copy",  // 上下文菜单
  // contextmenu: "link image table",
  content_style:
    "body { font-family:Helvetica,Arial,sans-serif; font-size:16px }",
  image_advtab: true,
  importcss_append: true,
  paste_webkit_styles: "all",
  paste_merge_formats: true,
  nonbreaking_force_tab: false,
  paste_auto_cleanup_on_paste: false,
  file_picker_types: "file",
  // 选中文字的快捷提示
  quickbars_selection_toolbar:
    "bold italic | quicklink h2 h3 blockquote quickimage quicktable",
  // 编辑器高度自适应
  autoresize_bottom_margin: 50,
  autoresize_max_height: 500,
  autoresize_min_height: 350,
  autoresize_on_init: true,
  autoresize_overflow_padding: 50,
  content_css: "../../../public/tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
  //图片上传
  images_upload_handler: (blobInfo, progress) =>
    new Promise((resolve, reject) => {
      let file = blobInfo.blob();
      console.log(blobInfo.blob(), "file");
      if (file.size / 1024 / 1024 > 200) {
        reject({
          message: "上传失败,图片大小请控制在 200M 以内",
          remove: true,
        });
      }
      const formData = new FormData();
      formData.append("file", file);
      loading.value = true;
      uploadImg(props.knwlgId, formData)
        .then((res) => {
          loading.value = false;
          resolve(
            import.meta.env.VITE_APP_BASE_API +
              "/ekms/images/v1/preview/" +
              res.data.imgId
          );
        })
        .catch(() => {
          loading.value = false;
        });
    }),
});

// 监听外部传递进来的的数据变化
watch(
  () => props.value,
  () => {
    myValue.value = props.value;
  }
);
//监听富文本中的数据变化
watch(
  () => myValue.value,
  () => {
    emits(
      "getContent",
      tinymce.activeEditor.getContent({ format: "text" }),
      myValue.value
    );
  }
);

//初始化编辑器
onMounted(() => {
  tinymce.init({});
});
</script>

<style lang="scss" scoped>
:deep(.tox-tinymce) {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  .tox-statusbar {
    display: none;
  }
}
</style>

补充:

1、引入中文语言包有两种方案:

  • 方案一:可以通过上面的第三步把所有语言包下载后,在初始化tinymce的时候指定语言及语言包
    language_url: "../../../public/tinymce/langs/zh_CN.js", // 语言包的路径,具体路径看自己的项目
    language: "zh_CN",
  • 方案二:直接下载Chinese Simplified后将下载下来的zh-Hans解压放入tinymce中
language_url: "../../../public/tinymce/langs/zh-Hans.js", // 语言包的路径,具体路径看自己的项目
language: "zh-Hans",

2、如果使用 tinymce.activeEditor.setContent发现没办法为编辑器赋值的话可以考虑使用setTimeout等编辑器init初始化完后再赋值内容:

setTimeout(()=>{
 tinymce.activeEditor.setContent('123')
},1000)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1076368.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

天锐绿盾加密软件——企业数据防泄密-CAD图纸、文档、源代码加密管理系统@德人合科技

天锐绿盾是一款专门为企业提供数据防泄密和文档加密管理的软件。该软件通过加密技术保护企业的核心数据&#xff0c;防止数据泄露和侵权行为&#xff0c;同时提供了全方位的文档加密管理系统&#xff0c;实现了对企业数据的安全保障和有效管理。 PC访问地址&#xff1a; isite…

使用安卓Termux+Hexo,手机也能轻松搭建个人博客网站

文章目录 前言1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址5.结语 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章&#xff0c;在几秒内&#xff0c;即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并…

Redis-01基本数据结构

1、String 1.1、介绍 String 是最基本的 key-value 结构&#xff0c;key 是唯一标识&#xff0c;value 是具体的值&#xff0c;value其实不仅是字符串&#xff0c; 也可以是数字&#xff08;整数或浮点数&#xff09;&#xff0c;value 最多可以容纳的数据长度是 512M 1.2、…

KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(1)

序言 最近在研究libdrm、DRM以及KWin&#xff0c;发现要真正理解Linux图形栈从上到下的机制&#xff0c;最好的、最易于理解的方法是将KWin、libdrm和DRM由上到下的调用过程暨代码统一进行研究&#xff0c;这样才能更好地理清其中的关系&#xff0c;把握总体全貌&#xff0c;因…

【WebService】C#搭建的标准WebService接口,在使ESB模版作为参数无法获取参数数据

一、问题说明 1.1 问题描述 使用C# 搭建WebService接口&#xff0c;并按照ESB平台人员的要求&#xff0c;将命名空间改为"http://esb.webservice",使用PostmanESB平台人员提供的入参示例进行测试时&#xff0c;callBussiness接口参数message始终为null。 以下是ES…

实验2.1.1 交换机的管理方式

实验2.1.1 交换机的管理方式 一、具体要求二、实验拓扑三、任务实施1.在PC机中使用默然参数连接交换机。3.通过system-view命令进入系统视图4.使用sysname重命名交换机为SWA。5.使用display current-configuration 命令查看交换机的配置信息。6.使用save命令保存配置信息。 一、…

35 WEB漏洞-逻辑越权之找回机制及接口安全

目录 找回重置机制接口调用乱用演示案例绑定手机验证码逻辑-Rep状态值篡改-实例某APP短信轰炸接口乱用-实例接口调用发包 文章分享&#xff1a;https://www.cnblogs.com/zhengna/p/15655691.html 有支付接口、短信发送接口&#xff0c;邮箱的发送接口等等&#xff0c;在接口这…

【算法挨揍日记】day12——153. 寻找旋转排序数组中的最小值、LCR 173. 点名

153. 寻找旋转排序数组中的最小值 153. 寻找旋转排序数组中的最小值 题目描述&#xff1a; 已知一个长度为 n 的数组&#xff0c;预先按照升序排列&#xff0c;经由 1 到 n 次 旋转 后&#xff0c;得到输入数组。例如&#xff0c;原数组 nums [0,1,2,4,5,6,7] 在变化后可能得…

嵌入式行业有无年龄危机?算不算青春饭?

今日话题&#xff0c;嵌入式行业到底算不算青春饭呢&#xff1f;在嵌入式行业工作两年半&#xff0c;我深刻体会到这个领域对技术的广泛要求&#xff0c;需要具备深厚而广泛的知识。因此&#xff0c;嵌入式行业的入门门槛相对较高。你需要了解软件和硬件&#xff0c;同时熟悉各…

使用EasyExcel导出复杂报表

1.效果图 2.请引入EasyExcel相关依赖&#xff0c;自行百度 3.controller Api(tags "下载中心接口") RestController RequestMapping("/basic/download") public class CspDownloadCenter extends BaseController {ApiOperation(value "复杂的exce…

Lesson10---list

lesson18: 一、 1.list是一个XX链表&#xff08;0&#xff1a;19&#xff1a;26&#xff09; 2.链表里面&#xff0c;单独存储数据最适合的结构是XX&#xff08;0&#xff1a;19&#xff1a;53&#xff09; 3.list的任意位置插入删除的时间复杂度是O(N)吗&#xff1f;&…

每日leetcode_2441_对应负数同时存在的最大整数

Leetcode每日一题_2441_对应负数同时存在的最大整数 记录自己的成长&#xff0c;加油。 题目 解题 class Solution {public int findMaxK(int[] nums) {int k -1;Set<Integer> set new HashSet<Integer>();for (int x : nums) {set.add(x);}for (int x : nums) …

springboot整合websocket开箱即用

springboot-websocket整合项目开箱即用&#xff0c;ws服务端&#xff0c;包含了在线客户监听&#xff0c;发送指定客户端数据&#xff0c;发送所有客户端数据。还可以根据指定转发给某个客户端。 WebSocketConfig配置缓存大小设置&#xff0c;设置异步发送操作的超时时间&#…

HTML5的新增表单元素

HTML5 有以下新的表单元素: <datalist> <keygen> <output> datalist datalist 元素规定输入域的选项列表。 datalist属性规定 form 或 input 域应该拥有自动完成功能。当用户在自动完成域中开始输入时&#xff0c;浏览器应该在该域中显示填写的选项&…

OSPF的原理与配置

第1章 OSPF[1] 本章阐述了OSPF协议的特征、术语&#xff0c;OSPF的路由器类型、网络类型、区域类型、LSA类型&#xff0c;OSPF报文的具体内容及作用&#xff0c;描述了OSPF的邻居关系&#xff0c;通过实例让读者掌握OSPF在各种场景中的配置。 本章包含以下内容&#xff1a; …

docker创建nginx容器

前言&#xff1a;当直接run运行nginx容器时&#xff0c;如果命令带有-v 映射出配置文件目录&#xff0c;则会报错&#xff0c;提示无法初始化&#xff0c;原因是没有配置文件&#xff0c;docker会同步主机文件到容器内&#xff0c;而主机文件又是空白的&#xff0c;所以无法启动…

选择工业交换机的外壳有什么要求?

在选择工业交换机时&#xff0c;我们通常更加注意工业交换机的温度范围、EMC电磁兼容性、安装方式和电源等方面&#xff0c;而对于工业交换机的外壳关注较少&#xff0c;除非客户有防水要求&#xff0c;那么&#xff0c;选择外壳有什么要求呢&#xff1f; 工业交换机的外壳采用…

华测监测预警系统 2.2 存在任意文件读取漏洞

华测监测预警系统 2.2 存在任意文件读取漏洞 一、 华测监测预警系统 2.2 简介二、漏洞描述三、影响版本四、fofa查询语句五、漏洞复现1、手动复现2、自动复现 六、修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信…

mac 版hadoop3.2.4 解决 Unable to load native-hadoop library 缺失文件

mac 版hadoop3.2.4或其他版本 Unable to load native-hadoop library 缺失文件 Native 包报错缺失&#xff1a; 1. hadoop-3.2.4/lib/native里加*.dylib 2. hadoop-3.2.4/etc/hadoop/hadoop-env.sh 加或修改 export HADOOP_OPTS"-Djava.library.path/Users/lvan/Documen…

a16z公布AI产品流量排名,ChatGPT占据榜首

&#x1f989; AI新闻 &#x1f680; a16z公布AI产品流量排名&#xff0c;ChatGPT占据榜首 摘要&#xff1a;美国风投公司a16z公布了针对C端用户的AI产品流量排名榜单。根据SimilarWeb的网站流量数据&#xff0c;ChatGPT位居榜首&#xff0c;占总流量的60%。排名第二的是Char…