123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- <template>
- <div id="wangEditor">
- <div :id="this.id" style="text-align: left"></div>
- </div>
- </template>
- <script>
- import E from 'wangeditor';
- import axios from 'axios';
- export default {
- name: 'wangEditor',
- props: {
- value: String,
- height: { type: Number, default: 300 }, //编辑区域高度
- zIndex: { type: Number, default: 200 }, //显示层级优先度
- placeholder: { type: String }, //未输入时显示提示
- isFocus: { type: Boolean, default: false }, //是否自动焦点(自动切换到富文本上)
- url: { type: String }, //上传地址,如果没有下面的两个,或者用的时候缺对应项,也用这个,如果都没有,就提示有问题
- imgSize: { type: Number, default: 5 }, //图片大小,单位MB,默认5MB
- imgAccept: { type: Array, default: () => ['jpg', 'jpeg', 'png', 'gif', 'bmp'] }, //图片类型
- imgOnceNumber: { type: Number, default: 5 }, //一次最多上传几个图片
- imgUrl: { type: String }, //图片上传地址
- videoSize: { type: Number, default: 1 }, //视频大小限制,单位为G,默认1G
- videoUrl: { type: String }, //视频上传地址
- imgLimit: { type: Array }, //img标签限制[width,height]
- },
- model: {
- prop: 'value',
- event: 'input',
- },
- data: function () {
- const getId = () => {
- let id = 'weditor';
- let i = 0;
- while (i < 20) {
- const num = Math.ceil(Math.random() * 10);
- id = `${id}${num}`;
- i++;
- }
- return id;
- };
- return {
- id: getId(),
- editor: undefined,
- imgObject: {},
- };
- },
- created() {},
- mounted() {
- this.init();
- },
- methods: {
- init() {
- const editor = new E(`#${this.id}`);
- // 使用设置
- editor.config.height = this.height;
- editor.config.zIndex = this.zIndex;
- editor.config.focus = this.isFocus;
- if (this.placeholder) editor.config.placeholder = this.placeholder;
- // 图片设置
- editor.config.uploadImgMaxSize = this.imgSize * 1024 * 1024;
- editor.config.uploadImgAccept = this.imgAccept;
- editor.config.uploadImgMaxLength = this.imgOnceNumber;
- // 视频
- editor.config.uploadVideoMaxSize = this.videoSize * 1024 * 1024 * 1024;
- // 默认设置
- // 图片-完全自定义上传
- editor.config.customUploadImg = async (resultFiles, insertImgFn) => {
- let url = this.imgUrl || this.url;
- if (!url) {
- this.$message.error('未配置上传路径!');
- return false;
- }
- for (const file of resultFiles) {
- const res = await this.upload(file);
- insertImgFn(res);
- }
- };
- // 视频-完全自定义上传
- editor.config.customUploadVideo = async (resultFiles, insertVideoFn) => {
- let url = this.videoUrl || this.url;
- if (!url) {
- this.$message.error('未配置上传路径!');
- return false;
- }
- for (const file of resultFiles) {
- const res = await this.upload(file);
- insertVideoFn(res);
- }
- };
- editor.config.onchange = (html) => {
- this.$emit('input', html);
- };
- // hooks
- editor.txt.eventHooks.clickEvents.push(this.toClick);
- editor.create();
- this.$set(this, `editor`, editor);
- },
- toClick(e) {
- // const target = e.target;
- // if (target.tagName == 'IMG') {
- // target.style.width = '150px';
- // target.style.height = '150px';
- // }
- },
- async upload(file) {
- let formdata = new FormData();
- formdata.append('file', file, file.name);
- const res = await axios.post(this.url, formdata, { headers: { 'Content-Type': 'multipart/form-data' } });
- if (res.status === 200 && res.data.errcode == 0) {
- const { id, name, uri } = res.data;
- return uri;
- } else {
- this.$message.error('上传失败');
- }
- },
- },
- watch: {
- value: {
- handler(val, oval) {
- this.$nextTick(() => {
- // 必须在nextTick下才可以获取this.editor,因为下面用了immediate,在mounted周期之前,但是init是在mounted中进行的.所以必须延迟到下个更新队列中
- // 且这个watch只是初始化用,因为上面用的v-model,有自己更新的方式;
- if (val && !oval) {
- this.editor.txt.html(val);
- }
- });
- },
- immediate: true,
- },
- },
- beforeDestroy() {
- // 销毁编辑器
- this.editor.destroy();
- this.editor = null;
- },
- };
- </script>
- <style lang="less" scoped></style>
|