下载资源
npm i tinymce tinymce/tinymce-vue
资源切换 tinymce-script-src
通过tinymce-vue远源码查看,可知加载tinymce是以script的形式加载的,默认加载的地址是cdn.tiny.cloud ,这应该是个外网地址,资源访比较慢。为了提高速度,将资源切换成本地的资源访问。
- 下载npm i tinymce或者通过 www.tiny.cloud/get-tiny/se… 下载tinymce
- 将tinymce复制到public中(public中的内容是不会编译的,是静态文件)
- 在tinymce-vue中传入
tinymce-script-src属性,值为/tinymce/tinymce.min.js。原理就是在public中的文件,可以直接通过/tinymce/tinymce.min.js访问到
但是下载tinymce是没有语言包的,你需要自己去下载然后复制到tinymce中,下载地址:www.tiny.cloud/get-tiny/la…
Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| v-model.value | 文本内容,可以是标签内容 | String | - | '' |
| id | 编辑器id,用于缓存内容时使用,相关内容看save插件,如果有多个编辑器确保id唯一 | string | - | '' |
| upload | 上传回调,详见upload | Function | - | null |
| init | 设置,详见init | Object | - | 详见init |
upload
上传函数,接受四个参数
| 参数 | 说明 |
|---|---|
| file | 上传的文件 |
| callback | 回调函数,接受一个字符串,表示上传文件的线上地址 |
| value | 现在输入框中线上文件的地址 |
| meta | 一个对象,{fieldname, filetype}, filetype 上传的类型,image:图片、file:链接、media:视频 |
v-model:value 这里比较简单,就不具体叙述了。但有一点是,可以不设置v-model,但是在使用保存按钮的时候,会将编辑器内容返回。所以内部并不是直接使用传过来的value,而是在内部定义一个变量,这个变量保持与value一致。
init
width
编辑器的宽
- 类型:string/number
- 默认:'100%'
height
编辑器的高
- 类型:string/number
- 默认:400
language
编辑器语言
- 类型:string
- 默认:'zh_CN'
plugins
编辑器插件,具体详见
- 类型:string
- 默认:'preview importcss searchreplace autolink save directionality code visualblocks visualchars fullscreen image link media template codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount help charmap quickbars emoticons'
tabbar
- 类型:string
- 默认:'redo bold italic strikethrough fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify numlist bullist | removeformat pagebreak ullscreen preview save image media link codesample'
“|”分割线的作用,当设置过多内容,一行显示不下,会出现折叠的情况,但是所有的tabar被“|”分为几个部分,并不是每个tabar单独分开。可以想象为每个“|”将tabbar分割为多个inline-black,计算一行能否显示是以当前这个inline-black能是显示,不能整个inline-black都隐藏
const toolbar = "redo bold italic strikethrough fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify numlist bullist | removeformat pagebreak ullscreen preview save image media link codesample ";
如上,比如最后一个inline-black显示不下,不是media link codesample等不显示,而是从removeformat之后的都不显示,即使加上removeformat能显示得下
menubar
菜单栏,设置false则不展示菜单栏详情见
- 类型:boolean/string
- 默认:'file edit view insert format tools table help'
image_advtab
上传图片的时候增加高级选项,可以调增样式
- 类型:boolean
- 默认:false
content_css
引入的额外样式,值为样式地址
- 类型:string
- 默认:''
content_style
- 类型:string
- 默认:''
样式内容,内容将作为style插入到样式head中
importcss_append
- 类型:boolean
- 默认:false
这个属性要结合content_css。在格式-格式中添加选项,选项为content_css定义的样式,只有 .类名{样式} 或 .类名.类名{样式} 或 标签.类名{样式} 才能插入到选项中
toolbar_mode
当tabbar一行显示不下的时候,点击显示更多按钮,其余的tabbar展示的模式。可选值为floating或者sliding,默认为floating
- 类型:string
- 取值:loating / sliding / scrolling / wrap
- 默认:wrap
contextmenu
右键时显示的菜单
- 类型:string
- 默认:link image imagetools table spellchecker
branding
是否显示tinymce的logo
- 类型:boolean
- 默认:false
toolbar_sticky
当编辑器超过一屏幕时,是否开启fixed布局
- 类型:boolean
- 默认:false
toolbar_sticky_offset
开启fixed布局后,top的值
- 类型:number
- 默认:0
media_url_resolver
此选项允许您指定一个函数,该函数将用于将 TinyMCE 的默认媒体嵌入逻辑替换为您自己的自定义逻辑。参数如下
- data:{url:string} url是用户输入的地址
- resolve:({html:string}) => void html表示插入页面的内容。如果html是空字符串,那么会自动以video的形式嵌入链接
- reject:({msg:string}) => void msg报错信息
media_url_resolver: function (data, resolve) {
console.log("media_url_resolver", data, resolve);
if (data.url.indexOf("bilibili") !== -1) {
const embedHtml = `<iframe src="${data.url}" width="600" height="600" ></iframe>`;
resolve({ html: embedHtml });
} else {
resolve({ html: "" });
}
},
这里识别是bilibili地址,然后以iframe的形式嵌入。width和height也会自动显示在输入框中,并支持修改
file_picker_callback
自定义上传,对应的插件是link media image。当点击这三个按钮的时候,出现的弹窗里面,会出现上传的按钮,如果不定义这个属性,就不会出现上传按钮。
参数如下:
- callback 回调函数
- value 当前的值
- meta
- fieldname 资源对应的属性
- filetype 那种类型上传 link:file、image:image、media:media 以上是meta公共的属性,对于不同的资源还有不同的属性
link的meta:
- text 显示的文本
- title 链接的title
image的meta
- alt 图片属性的alt
media的meta
- width和height 视频的width和height
save_onsavecallback
保存按钮的回调函数,参数editor实例,对应的plugin是save
save_enablewhendirty
默认保存按钮只有在内容变化的时候才能点击,点击时候也不能在点击了。设置这个属性为false,可以随时点击保存按钮
- 类型:Boolean
- 默认:true
autosave_interval
自动保存的间隔时间,
- 类型:String
- 默认:'30s'
autosave_prefix
自动保存,会存放到localstorage中,此参数设置localstorage对应key的前缀
- 类型:String
- 默认:"tinymce-autosave-{path}{query}-{id}-"
autosave_restore_when_empty
当内容为空的时候,是否自动从localstorage中获取
- 类型:Boolean
- 默认:false
autosave_retention
localstorage的有效时间。
- 类型:String
- 默认:'20m'
image_list
上传图片的时候提供可选择的图片。title是下拉的label,value是选中的图片的地址
- 类型:array / url / function
- 默认:[]
image_list: [
{ title: 'Cat', value: 'cat.png' },
{ title: 'Dog', value: 'dog.jpg' }
]
image_class_list
上传图片的时候提供可选择的class
- 类型:array
- 默认:[]
image_caption
上传图片的会增加一个是否显示标题的功能,选择之后,默认之后默认为caption,用户可以点击修改
skin
皮肤
- 类型:string
- 默认:''
skin_url
引入的外部皮肤地址
- 类型:string
- 默认:''
init的file_picker_callback会覆盖upload函数
这里只是介绍了默认属性,还有很多配置参数,大家可以自行查看tinymce中文文档
Events
| 事件名称 | 说明 | 回调参数 |
|---|---|---|
| init | 组件初始化完成 | e:事件 editor:编辑器实例 |
| save | 保存 | 编辑器内容 |
完整代码
<template>
<Editor
tinymce-script-src="/tinymce/tinymce.min.js"
:model-value="valueThis"
:init="initThis"
@update:model-value="change"
/>
</template>
<script lang="ts">
import { toRefs, watch, ref } from "vue";
import Editor from "@tinymce/tinymce-vue";
import getInit, { filePickerCallback } from "./init";
import plugins from "./plugins";
export default {
name: "JhEditor",
components: {
Editor,
},
props: {
value: {
type: String,
default: "",
},
id: {
type: String,
default: "",
},
upload: {
type: Function,
default: null,
},
init: {
type: Object,
default: () => {
return {};
},
},
},
emits: ["update:value"],
setup(props, { attrs, emit }) {
console.log("attr", attrs);
const { upload, init, value, id } = toRefs(props);
if (upload.value) {
init.value.file_picker_callback = filePickerCallback(upload.value);
}
if (id.value) {
init.value.plugin = "autosave";
init.value.autosave_prefix = id.value;
init.value.plugins = plugins + " autosave";
}
const valueThis = ref("");
watch(
value,
(val) => {
valueThis.value = val;
},
{
immediate: true,
}
);
const save = (a, b) => {
emit("save", valueThis.value);
};
init.value.save_onsavecallback = save;
const initThis = getInit(init.value);
const change = (val) => {
valueThis.value = val;
emit("update:value", val);
};
return {
change,
initThis,
valueThis,
};
},
};
</script>
使用代码
<template>
<div class="show_block">
content:{{ content }}
<a-button type="primary" @click="aaa">修改内容</a-button>
</div>
<JhEditor
id="id"
v-model:value="content"
:upload="upload"
@save="save"
@init="init"
/>
</template>
<script lang="ts" setup>
import { ref } from "vue";
const content = ref("111");
const upload = (file, callback, value, meta) => {
console.log(meta);
console.log("file", file);
setTimeout(() => {
callback("https://www.baidu.com/img/bd_logo1.png");
}, 1000);
};
const save = (val) => {
console.log("保存", val);
};
const init = (e, editor) => {
console.log("e", e);
console.log("editor", editor);
};
const aaa = () => {
content.value = "修改之后的内容";
};
</script>
<style type="text/css">
.show_block {
margin-bottom: 10px;
}
</style>