使用的是tinymce第三方插件
npm install tinymce
npm install @tinymce/tinymce-vue
封装组件
components下新增editor目录
新增editor.vue文件
/**
* 富文本编辑器组件
* (c) 2024-02
* @param {String} value 绑定的数据字段
* @param {Boolean} disabled 是否禁用,默认值 false
* @param {Boolean} menubar 是否显示菜单栏,默认值 false
* @param {Boolean} statusbar 是否显示状态栏,默认值 true
* @param {Boolean} resize 是否可以拖动高度,默认值 true
* @param {Number} height 编辑器高度,默认值 400
* @param {String | Array} plugins 编辑器插件
* @param {String | Array} toolbar 编辑器工具栏
* @example: <editor v-model="editorHtml" :height="300"></editor>
*/
<template>
<div class="editor">
<tinymce-editor v-model="myValue" :init="init" :disabled="disabled" @onBlur="onBlur" @onChange="onChange" @onClick="onClick" @onFocus="onFocus" @onInit="onInit"></tinymce-editor>
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce';
import tinymceEditor from '@tinymce/tinymce-vue';
import 'tinymce/themes/silver/theme';
import 'tinymce/models/dom' // 这里是个坑 一定要引入
import 'tinymce/icons/default'; //引入编辑器图标icon,不引入则不显示对应图标
// 编辑器插件plugins,更多插件参考:https://www.tiny.cloud/docs/plugins/
import 'tinymce/plugins/link'; // 插入链接插件
import 'tinymce/plugins/image'; // 插入图片插件
import 'tinymce/plugins/media'; // 插入视频插件
import 'tinymce/plugins/table'; // 插入表格插件
import 'tinymce/plugins/lists'; // 列表插件
import 'tinymce/plugins/code'; // 代码插件
import 'tinymce/plugins/wordcount'; // 字数统计插件
export default {
name: 'editor',
components: {
tinymceEditor
},
props: {
// 绑定的数据字段
value: {
type: String,
default: ''
},
// 是否禁用
disabled: {
type: Boolean,
default: false
},
// 是否显示菜单栏
menubar: {
type: Boolean,
default: true
},
// 是否显示状态栏
statusbar: {
type: Boolean,
default: true
},
// 是否可以拖动高度
resize: {
type: Boolean,
default: true
},
// 编辑器高度
height: {
type: Number,
default: 400
},
// 编辑器插件
plugins: {
type: [String, Array],
default: 'link image media table lists code wordcount'
},
// 编辑器工具栏
toolbar: {
type: [String, Array],
default: 'undo redo | fontsizeselect | bold italic underline forecolor backcolor | alignleft aligncenter alignright alignjustify | table link image media | code removeformat'
// default: 'undo redo | formatselect | fontsizeselect | bold italic underline strikethrough superscript subscript forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link lists image media table | code wordcount removeformat'
}
},
data() {
return {
myValue: this.value,
init: {
language_url: '/tinymce/langs/zh_CN.js',
language: 'zh_CN',
skin_url: '/tinymce/skins/ui/oxide',
content_css: '/tinymce/skins/ui/oxide/content.min.css',
height: this.height || 400,
plugins: this.plugins,
toolbar: this.toolbar || false,
branding: false,
menubar: this.menubar,
statusbar: this.statusbar,
resize: this.resize
}
};
},
mounted() {
tinymce.init({});
},
methods: {
onBlur(e) {
this.$emit('onBlur', e, tinymce);
},
onChange(e) {
this.$emit('onChange', e, tinymce);
},
onClick(e) {
this.$emit('onClick', e, tinymce);
},
onFocus(e) {
this.$emit('onFocus', e, tinymce);
},
onInit(e) {
this.$emit('onInit', e, tinymce);
}
},
watch: {
value(val) {
this.myValue = val;
},
myValue(val) {
this.$emit('input', val);
}
}
};
</script>
同目录下新增导出文件index.js
export { default } from './editor.vue';
需要注意!!!
有几个样式文件和语言文件需要单独引入到public目录下
最后就可以直接导入使用了
<template>
<div class="app-container">
<editor :value="editorHtml" @input="editorInput" :height="300"></editor>
<el-button type="primary" @click="save">保存</el-button>
</div>
</template>
<script lang="ts" setup>
import {reactive, ref} from "vue";
import Editor from "@/components/editor/index";
const editorHtml = ref('')
const editorInput = (e: any)=>{
editorHtml.value = e
}
const save = () => {
console.log('editorHtml', editorHtml.value);
}
</script>