效果
“@tinymce/tinymce-vue”: “^3.2.3”,
“tinymce”: “^5.5.0”,
一、安装
npm install tinymce -S
和
npm install @tinymce/tinymce-vue -S
二、下载资源
将下面两个资源下载下载,放到资源文件里面。下载tinymce文件的目的是解决加载缓慢,白屏问题
tinymce资源文件下载地址
根据相应的版本下载
三、创建组件开始使用
- 1、解决加载缓慢,白屏问题
把上面下载的tinymce文件放在资源文件后,需要在index.html中引入使用tinymce.min.js
<script src="/static/tinymce/tinymce.min.js"></script>
-
2、组件完整代码
html
<editor :init="editorInit" v-model="contentHtml" :disabled="disabled" :autoresize="autoresize" />
<!-- 上传视频没有一个正在上传的遮罩,那么就需要自己写一个遮罩,就如下面的div,我这里只做展示,样式没有写 -->
<div v-if="loading" />
js
import Editor from "@tinymce/tinymce-vue";
// import 'tinymce/plugins/media'
// 后端上传接口,按照需求而定
import {
upload,
} from "../api/api";
import request from "../api/request";
import store from '../store/index'
import util from '../Util'
var util={}
export default {
name: "TinyMceEditor",
model: {
prop: "content",
event: "change",
},
props: {
// 绑定的文本内容
content: {
type: String,
default: "",
},
// 是否禁止输入
disabled: {
type: Boolean,
default: false,
},
// true则自适应高
autoresize: {
type: Boolean,
default: false,
},
},
components: {
Editor,
},
data: () => ({
// 编辑器配置
editorInit: {
language_url: "/static/zh_CN.js", //汉化文件的路径, 这里的原始路径是'/public/zh_CN.js'
language: "zh_CN",
height: 500,
menubar: true,
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table paste code help wordcount",
"image media",
],
toolbar: "undo redo | formatselect | bold italic underline strikethrough superscript subscript codeformat forecolor backcolor removeformat| \
alignleft aligncenter alignright alignjustify outdent indent lineheight| \
bullist numlist | link image media template codesample inserttable table | \
charmap emoticons hr insertdatetime | cut copy newdocument print | \
spellchecker |searchreplace preview fullscreen | help | ",
file_picker_types: ' media',
content_css: 'css/content.css',
// 自定义视频上传
file_picker_callback: function (cb, value, meta) {
if (meta.filetype == 'media') {
//创建一个隐藏的type=file的文件选择input
let input = document.createElement('input');
input.setAttribute('type', 'file');
input.onchange = function (e) {
let file = e.target.files[0]; //只选取第一个文件。如果要选取全部,后面注意做修改
store.commit('setParam', {
loading: true
})
const formData = new FormData();
formData.append("file", file);
request(upload, formData)
.then((res) => {
store.commit('setParam', {
loading: false
})
if (res.code === 0) {
let fileUrl = res.data.url;
cb(fileUrl, {
title: file.name
});
return;
}
util.message("err", "上传失败")
})
.catch(() => {
store.commit('setParam', {
loading: false
})
util.message("err", "上传失败")
});
}
//触发点击
input.click();
}
},
//自定义逻辑替换 Tinymce 的默认媒体嵌入逻辑 --处理添加视频显示问题
media_url_resolver: function (data, resolve) {
try {
let videoUri = encodeURI(data.url);
let embedHtml
if (videoUri) {
embedHtml = `<p>
<span
class="mce-object mce-object-video"
data-mce-selected="1"
data-mce-object="video"
data-mce-p-width="100%"
data-mce-p-height="auto"
data-mce-p-controls="controls"
data-mce-p-controlslist="nodownload"
data-mce-p-allowfullscreen="true"
data-mce-p-src=${videoUri} >
<video src=${data.url} width="100%" height="auto" controls="controls" controlslist="nodownload">
</video>
</span>
</p>
<p style="text-align: left;"></p>`;
} else {
embedHtml = ""
}
resolve({
html: embedHtml
});
} catch (e) {
resolve({
html: ""
});
}
},
branding: false,
// 自定义图片上传
images_upload_handler: (blobInfo, success, failure) => {
const formData = new FormData();
formData.append("file", blobInfo.blob());
request(upload, formData)
.then((res) => {
if (res.code === 0) {
let file = res.data.url;
success(file);
return;
}
failure("上传失败");
})
.catch(() => {
failure("上传出错");
});
},
},
contentHtml: "",
updateTimer: null, //防抖
}),
computed: {
loading() {
return store.state.loading
}
},
watch: {
content(valueFromParent) {
// 由父组件自动修改的内容,同步到子组件
if (valueFromParent !== this.contentHtml) {
this.contentHtml = valueFromParent;
}
},
contentHtml(valueFromChild = "") {
// 向父组件派发change事件
if (valueFromChild !== this.content) {
this.$emit("change", valueFromChild);
}
},
},
created() {
store.commit('setParam', {
loading: false
})
},
beforeDestroy() {
this.updateTimer && clearTimeout(this.updateTimer);
},
};
plugins
和toolbar
是成对存在的,plugins必不可少,
toolbar是页面中操作栏导航的排列
四、一些需求实现
1、在光标处插入内容
在光标处插入内容,此方法会有插入后立即删除却删不掉的问题
tinyMCE.activeEditor.selection.setContent(`<span style="color:red">{total_score}</span>`)
在光标处插入内容,这个比较完美
tinyMCE.activeEditor.execCommand('mceInsertContent',false,`<span style="color:red">{total_score}</span>`);
2、获取内容、设置内容
- 如果当前页面只有一个编辑器
tinyMCE.activeEditor.getContent() //获取内容
tinyMCE.activeEditor.setContent('需要设置的编辑器内容') //设置内容
- 如果当前页面有多个编辑器
tinyMCE.editors[0].getContent() //获取第一个编辑器的内容
tinyMCE.editors[0].setContent('需要设置的编辑器内容') //设置第一个编辑器的内容
- 获取不带HTML标记的纯文本内容
取到的 text 即为纯文本内容
var activeEditor = tinymce.activeEditor;
var editBody = activeEditor.getBody();
activeEditor.selection.select(editBody);
var text = activeEditor.selection.getContent({'format': 'text'});