vue2使用富文本编辑器vue-quill-editor(自定义上传视频)

效果图:

 一、 安装vue-quill-editor

npm install vue-quill-editor -S

//若是报错 Cannot read property 'imports' of undefined,请安装
// 为了避免意外还是先安装一下quill
npm install quill --save
1.2.、全局引入在main.js 中写入
// 富文本编辑器
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor)
1.3、再页面中引入
<template>
    <div>
        <quill-editor  ref="myQuillEditor" v-model="content" :options="editorOption" 
      class="my-quill-editor"></quill-editor>
    </div>
</template>

<script>
export default {
    data() {
        return {
            content: '',
            editorOption: {
                // 占位配置
                placeholder: '请输入...',
                height: '300px',
                modules: {
                    // 配置工具栏
                    toolbar: {
                        container: [
                            ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
                            ['blockquote', 'code-block'], // 引用  代码块
                            [{ header: 1 }, { header: 2 }], // 1、2 级标题
                            [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
                            [{ script: 'sub' }, { script: 'super' }], // 上标/下标
                            [{ indent: '-1' }, { indent: '+1' }], // 缩进
                            [{ direction: 'rtl' }], // 文本方向
                            ['link', 'image', 'video'], // 链接、图片、视频
                            [{ align: [] }], // 添加居中按钮
                            [{ color: [] }], // 文字颜色按钮
                        ]
                    },
                    // 更改插入的图片大小
                    imageResize: {
                        displayStyles: {
                            backgroundColor: "black",
                            border: "none",
                            color: "white",
                        },
                        modules: ["Resize", "DisplaySize", "Toolbar"],
                    },
                }
            },
        }
    }
}
</script>
<style>
    /* 编辑器高度及背景色 */
    ::v-deep .ql-editor {
        min-height: 300px;
        background-color: #fff;
    }
</style>

二、  更改插入图片大小、  安装

npm install quill
npm install quill-image-resize-module --save
npm install quill-image-drop-module --save
2.1、 main.js引入
// 富文本图片大小
import imageResize  from 'quill-image-resize-module' // 调整大小组件。
import { ImageDrop } from 'quill-image-drop-module'; // 拖动加载图片组件。
Quill.register('modules/imageResize', imageResize );
Quill.register('modules/imageDrop', ImageDrop);
2.2、 在vue.config.js文件中引入
//下载 webpack
npm install webpack -s

// vue.config.js :

const webpack = require('webpack');
module.exports = {
  configureWebpack: {
    // 在这里添加你的自定义Webpack配置
    plugins: [
      new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js',
        'Quill': 'quill/dist/quill.js'
      })
    ]
  }
};

配置完成后记得重启一下

 2.3、 在页面中显示样式
<template>
    <div>
        // 添加  class="ql-editor" 样式,不然文字居中不会显示
        <div v-html="content" class="ql-editor"></div>
    </div>
</template>
2.4、 图片适配PC后,手机端显示太大,如果只有一处调用就在页面中添加css样式,如何多次调用在app.vue中添加css样式 
/* PC端样式 */
@media (min-width: 768px) {
  .ql-editor img {
    max-width: 100%;
    height: auto;
  }
}

/* 手机端样式 */
@media (max-width: 767px) {
  .ql-editor img {
    width: 100%;
    height: auto;
  }
}
2.5、 如果富文本编辑器内容过多,会将富文本编辑器功能按钮移除屏幕

解决方法,固定高度,使用默认滚动条

.ql-toolbar.ql-snow+.ql-container.ql-snow {
    height: 600px;
}

三、自定义视频上传

3.1、添加组件,引入修改的video模块并注册、替换默认上传
<template>
    <div>
        <quill-editor  ref="myQuillEditor" v-model="content" :options="editorOption" 
      class="my-quill-editor"></quill-editor>
        // 上传组件
        <el-dialog title="视频" :visible.sync="dialogFormVisible" style="text-align: center;">
      <el-upload class="upload-demo" drag action="上传地址" multiple
        :before-upload="onBeforeUploadVideo" :on-success="onSuccessVideo"
        :on-error="onErrorVideo">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传MP4文件,且不超过10M</div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
      </div>
    </el-dialog>
    </div>
</template>

<script>
// 这里引入修改的video模块并注册,utils/quillVideo在下方复制
import Video from "@/utils/quillVideo";
Quill.register(Video, true);
export default {
    data() {
        return {
            content: '',
            dialogFormVisible: false,
            editorOption: {
                // 占位配置
                placeholder: '请输入...',
                height: '300px',
                modules: {
                    // 配置工具栏
                    toolbar: {
                        container: [
                            ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
                            ['blockquote', 'code-block'], // 引用  代码块
                            [{ header: 1 }, { header: 2 }], // 1、2 级标题
                            [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
                            [{ script: 'sub' }, { script: 'super' }], // 上标/下标
                            [{ indent: '-1' }, { indent: '+1' }], // 缩进
                            [{ direction: 'rtl' }], // 文本方向
                            ['link', 'image', 'video'], // 链接、图片、视频
                            [{ align: [] }], // 添加居中按钮
                            [{ color: [] }], // 文字颜色按钮
                        ],
                        handlers: {
                            // 点击上传视频阻止默认上传替换成自定义上传
                            video: () => {
                                this.dialogFormVisible = true;
                            },
                        },
                    },
                    // 更改插入的图片大小
                    imageResize: {
                        displayStyles: {
                            backgroundColor: "black",
                            border: "none",
                            color: "white",
                        },
                        modules: ["Resize", "DisplaySize", "Toolbar"],
                    },
                }
            },
        }
    }
}
</script>
<style>
    /* 编辑器高度及背景色 */
    ::v-deep .ql-editor {
        min-height: 300px;
        background-color: #fff;
    }
</style>

 

// 这是 utils/quillVideo

import { Quill } from "vue-quill-editor";
// 源码中是import直接倒入,这里要用Quill.import引入
const BlockEmbed = Quill.import("blots/block/embed");
const Link = Quill.import("formats/link");

const ATTRIBUTES = ["height", "width"];

class Video extends BlockEmbed {
  static create(value) {
    const node = super.create();
    // 添加video标签所需的属性
    node.setAttribute('style', 'object-fit:fill;width: 30%;')
    node.setAttribute('preload', 'auto')    // auto - 当页面加载后载入整个视频  meta - 当页面加载后只载入元数据  none - 当页面加载后不载入视频
    // node.setAttribute('playsinline', 'true')
    // node.setAttribute('x-webkit-airplay', 'allow')
    // node.setAttribute('x5-video-player-type', 'h5') // 启用H5播放器,是wechat安卓版特性
    // node.setAttribute('x5-video-orientation', 'portraint') // 竖屏播放 声明了h5才能使用  播放器支付的方向,landscape横屏,portraint竖屏,默认值为竖屏
    // node.setAttribute('x5-playsinline', 'true') // 兼容安卓 不全屏播放
    node.setAttribute('x5-video-player-fullscreen', 'true')    // 全屏设置,设置为 true 是防止横屏
    node.setAttribute('controlsList', 'nofullscreen') // 控制删除

    node.setAttribute("poster", value.poster); // 视频封面
    node.setAttribute("controls", "controls");
    node.setAttribute("type", "video/mp4");
    node.setAttribute("src", this.sanitize(value.url));
    return node;
  }

  static formats(domNode) {
    return ATTRIBUTES.reduce((formats, attribute) => {
      if (domNode.hasAttribute(attribute)) {
        formats[attribute] = domNode.getAttribute(attribute);
      }
      return formats;
    }, {});
  }

  static sanitize(url) {
    return Link.sanitize(url);
  }

  static value(domNode) {
    return  {
        url: domNode.getAttribute("src"),
        poster: domNode.getAttribute('poster'),
    }
  }

  format(name, value) {
    if (ATTRIBUTES.indexOf(name) > -1) {
      if (value) {
        this.domNode.setAttribute(name, value);
      } else {
        this.domNode.removeAttribute(name);
      }
    } else {
      super.format(name, value);
    }
  }

  html() {
    const { video } = this.value();
    return `<a href="${video}">${video}</a>`;
  }
}
Video.blotName = "video"; // 这里不用改,楼主不用iframe,直接替换掉原来,如果需要也可以保留原来的,这里用个新的blot
Video.className = "ql-video";
Video.tagName = "video"; // 用video标签替换iframe

export default Video;
3.2、组件中的poster是视频封面,若不上传手机端只显示开始按钮,其余部分为空白()
quill.insertEmbed(index, "video", { url: videoLink, poster: 'https://7up.pics/images/2024/01/23/101sh.png' });
methods: {
    // el-文件上传组件
        onBeforeUploadVideo(file) {
            let acceptArr = ["video/mp4"];
            const isVideo = acceptArr.includes(file.type);
            const isLt1M = file.size / 1024 / 1024 < 30;
            if (!isVideo) {
                this.$message.error("只能上传mp4格式文件!");
            }
            if (!isLt1M) {
                this.$message.error(`上传文件大小不能超过 30MB!`);
            }
            return isLt1M && isVideo;
        },
        // 文件上传成功时的钩子
        onSuccessVideo(res) {
            if (res.code === 2000) {
                this.insertVideoLink(BASE_URL + res.data);
            } else {
                this.$message.error(res.message);
            }
        },
        // 文件上传失败时的钩子
        onErrorVideo() {
            this.$message.error("上传失败");
        },
        // 插入视频
        insertVideoLink(videoLink) {
            if (!videoLink) return this.$message.error("视频地址不能为空!");
            this.dialogFormVisible = false;
            let quill = this.$refs["myQuillEditor"].quill;
            // 获取富文本
            let range = quill.getSelection();
            // 获取光标位置:当编辑器中没有输入文本时,这里获取到的 range 为 null
            let index = range ? range.index : 0;
            // 在光标所在位置 插入视频
            quill.insertEmbed(index, "video", { url: videoLink, poster: 'https://7up.pics/images/2024/01/23/101sh.png' });
            // 调整光标到最后
            quill.setSelection(index + 1);
        },
}

四、提示:组件上传地址,传参,token需自行完成Element-UI中的el-upload有参数api

Element - The world's most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库icon-default.png?t=N7T8https://element.eleme.cn/#/zh-CN/component/upload

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值