用来用去还是用回了ueditor-Vue富文本编辑器二次扩展。我们使用用过UEditor、TinyMCE、CKEditor、wangEditor、Tiptap、Quill项目经历过多次富文本的编辑器的选型使用,发现现在新的富文本编辑总感觉还是没达到我们的要求,果然改回了ueditor。
UEditor 是由百度WEB前端研发部开发的一款所见即所得的开源富文本编辑器。它具有轻量、可定制、用户体验优秀等特点,并且基于MIT开源协议(也有说法是基于BSD协议),所有源代码在协议允许范围内可自由修改和使用。UEditor的推出,有效降低了网站开发者的开发成本,节约了他们在开发富文本编辑器方面所需的大量时间。
一、系统特点
分层架构设计:UEditor在设计上采用了经典的分层架构设计理念,包括核心层、命令插件层和UI层,以实现功能层次之间的轻度耦合。
核心层:提供编辑器底层的方法和概念,如DOM树操作、Selection、Range等。
命令插件层:所有的功能型实现都通过这一层中的命令和插件来完成,各个命令和插件之间基本互不耦合,方便定制与扩展。
UI层:与核心层和命令插件层几乎完全解耦,简单的配置即可为编辑器在界面上添加额外的UI元素和功能。
二、优点
体积小巧,性能优良:UEditor在保证功能全面的同时,尽量减少了体积,提升了性能。
使用简单:对于开发者来说,UEditor易于上手,可以快速集成到项目中。
多浏览器支持:支持Mozilla、MSIE、FireFox、Maxthon、Safari和Chrome等多种浏览器。
丰富完善的中文文档:为开发者提供了详尽的中文文档,方便学习和使用。
vue-ueditor-wrap 是一个Vue组件,它封装了UEditor(百度富文本编辑器)以便更容易地在Vue项目中集成和使用。UEditor是一个功能强大的富文本编辑器,但直接将其集成到Vue项目中可能会遇到一些兼容性和维护性的问题,而vue-ueditor-wrap正是为了解决这些问题而设计的。
如何使用 vue-ueditor-wrap
-
安装
首先,你需要通过npm或yarn来安装vue-ueditor-wrap。打开你的终端或命令提示符,然后运行以下命令之一:
bash复制代码
npm install vue-ueditor-wrap --save 或者
bash复制代码
yarn add vue-ueditor-wrap -
扩展组件
接下来,在你的Vue组件中引入vue-ueditor-wrap。
<template> <div style="border: 1px solid #ccc"> <vue-ueditor-wrap v-model="data" :config="editorConfig" :editorDependencies="['ueditor.config.js', 'ueditor.all.js']" ref="editorRef" ></vue-ueditor-wrap> <diy-storage ref="storageImg" style="display: none" @confirm="getAttachmentFileList"></diy-storage> <diy-storage ref="storageVideo" type="video" accept=".rm,.rmvb,.wmv,.avi,.mpg,.mpeg,.mp4" style="display: none" @confirm="getAttachmentVideoFileList" ></diy-storage> </div> </template> <script setup name="DiyEditor"> import { ref } from 'vue'; import { VueUeditorWrap } from 'vue-ueditor-wrap'; import { useVModel } from '@vueuse/core'; import DiyStorage from '@/components/upload/storage.vue'; import { Session } from '@/utils/storage'; const editorRef = ref(); const storageImg = ref(null); const storageVideo = ref(null); const props = defineProps({ modelValue: { type: String, default: '', }, height: { type: Number, default: 300, }, }); const emit = defineEmits(['update:modelValue', 'handleBlur']); const data = useVModel(props, 'modelValue', emit); const serverHeaders = { Authorization: Session.get('token'), }; const editorConfig = ref({ debug: false, UEDITOR_HOME_URL: import.meta.env.MODE == 'development' ? '/public/ueditor/' : import.meta.env.VITE_BUILD_DIR + '/ueditor/', serverUrl: (process.env.NODE_ENV === 'production' ? '' : '/api') + '/sys/storage/upload', serverHeaders, // 编辑器不自动被内容撑高 autoHeightEnabled: false, // 初始容器高度 initialFrameHeight: props.height, // 初始容器宽度 initialFrameWidth: '100%', toolbarCallback: function (cmd, editor) { editorRef.value = editor; if (cmd == 'insertimage') { storageImg.value.handleStorageDlg('', '上传图片'); return true; } else if (cmd == 'insertvideo') { storageVideo.value.handleStorageDlg('', '上传视频'); return true; } }, }); const getAttachmentFileList = (files) => { if (!files.length) { return; } files.forEach((element) => { editorRef.value?.execCommand('insertHtml', "<img src='" + element.url + "'/>"); }); }; const getAttachmentVideoFileList = (files) => { if (!files.length) { return; } files.forEach((element) => { editorRef.value?.execCommand('insertHtml', "<video src='" + element.url + "'/>"); }); }; </script>
注意:v-model用于双向绑定编辑器的内容,config属性用于传递UEditor的配置选项。
-
配置UEditor
你可以通过:config属性向vue-ueditor-wrap传递UEditor的配置选项。这些选项会直接影响编辑器的行为和外观。UEditor提供了大量的配置项,你可以根据自己的需求进行调整。
-
注意事项
- 确保你已经按照vue-ueditor-wrap的文档和UEditor的官方文档正确配置了编辑器。
- 如果你在Vue CLI项目中工作,可能需要处理静态资源(如UEditor的JS和CSS文件)的路径问题。
- vue-ueditor-wrap可能会随着版本的更新而发生变化,因此建议查阅最新的文档和更新日志。
-
调试和测试
在集成vue-ueditor-wrap之后,你应该在多个浏览器和设备上测试你的Vue应用,以确保编辑器能够正常工作并且符合你的要求。
-
组件调用实现
<template>
<div class="container">
<div class="flex diygw-col-24">
<el-form-item prop="editor" class="diygw-el-rate" label="多行输入" label-width="80px">
<diy-editor v-model="editor"></diy-editor>
</el-form-item>
</div>
<div class="clearfix"></div>
</div>
</template>
<script>
import { useRouter, useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '@/stores/userInfo';
import { ElMessageBox, ElMessage } from 'element-plus';
import DiyEditor from '@/components/editor/index.vue';
export default {
components: {
DiyEditor
},
data() {
return {
globalOption: {},
userInfo: {},
roleDatas: {
rows: [
{
status: '',
flag: '',
remark: '',
roleId: 0,
roleName: '',
roleKey: '',
dataScope: '',
roleSort: 0,
createTime: '',
updateTime: '',
deleteTime: null,
userId: null,
updateUserId: null
}
],
total: 0,
code: 0,
msg: ''
},
editor: ''
};
},
methods: {
getParamData(e, row) {
row = row || {};
let dataset = e.currentTarget ? e.currentTarget.dataset : e;
if (row) {
dataset = Object.assign(dataset, row);
}
return dataset;
},
navigateTo(e, row) {
let dataset = this.getParamData(e, row);
let { type } = dataset;
if (type == 'page' || type == 'inner' || type == 'href') {
this.router.push({
path: dataset.url,
query: dataset
});
} else if (typeof this[type] == 'function') {
this[type](dataset);
} else {
ElMessage.error('待实现点击事件');
}
},
async init() {},
// 新增接口 API请求方法
async roleDatasApi(param, data) {
param = param || {};
param = this.getParamData(param);
let http_url = '/sys/role/all';
let http_data = {
tt: param.tt || '1',
te: param.te || this.t523 || '123'
};
let http_header = {
'Content-Type': 'application/json',
'Content-Length': '123'
};
let roleDatas = await this.$http.post(http_url, http_data, http_header, 'json');
this.roleDatas = roleDatas;
}
},
async mounted() {
this.router = useRouter();
this.globalOption = useRoute().query;
const stores = useUserInfo();
const { userInfos } = storeToRefs(stores);
this.userInfo = userInfos;
await this.init();
},
beforeUnmount() {}
};
</script>
<style lang="scss" scoped>
.container {
font-size: 12px;
}
</style>
通过使用vue-ueditor-wrap,你可以轻松地将UEditor集成到你的Vue项目中,从而为用户提供一个功能丰富的文本编辑体验。
扩展组件代码已开源至https://gitee.com/diygw/diygw-ui-admin
大家可以前往下载