Vue-Quill-Editor + Element 实现富文本自定义上传图片和视频

Vue-Quill-Editor 富文本编辑器和 Element-ui 的安装和使用各大博客论坛已经有很多,这里不再赘述。

图片上传:

Vue-Quill-Editor 上传图片默认转换成base64的形式,存储在数据库里会很长,于是使用文件上传服务器的路径来存储。

<quill-editor
    v-model="content"
    ref="myQuillEditor"
    class="ql-editor-class"
    :options="editorOption"
>
</quill-editor>
<el-upload
    style="display: none"                                //隐藏
    class="quill-picture-uploader"                       //类名,不能重复
    action="http://localhost:8080/project/uploadPic"     //后台上传接口
    :before-upload="bfUpload"                            //上传之前调用
    :on-success="uploadSuccess"                          //上传成功调用
    :headers="myHeaders"                                 //token,非必要
>
</el-upload>
data() {
    return {
      //图片url
      urlList: [],
      //正文
      content: "",
      //富文本配置
      editorOption: {
        placeholder: "正文内容支持上传图片和视频",
        theme: "snow",
        modules: {
          toolbar: {
            container: toolbarOptions,     //自定义工具栏,略
            handlers: {
              image: function (value) {    //替换原图片上传功能
                if (value) {
                  document.querySelector(".quill-picture-uploader input").click(); //核心
                } else {
                  this.quill.format("image", false);
                }
              },
            }
          },
        },
      },
    };
  },

F12查看一个 element-upload 组件可以看到它的结构是这样的。querySelector() 方法返回文档中匹配指定 CSS 选择器的一个元素,具体用法可以百度了解。这句代码的意思就是触发指定类名元素下,input元素的点击事件,达到点击编辑器里的图片上传按钮,却触发 element-upload 上传方法的效果。

//上传图片之前校验
bfUpload(file) {
    console.log(file)
    if ("image/png" == file.type || "image/jpeg" == file.type) {
    } else {
        this.$message.error('图片插入失败,请检查文件格式');
        return;
    }
},
//正文插入图片上传成功调用
uploadSuccess(response, file, fileList) {
    this.urlList.push(response.url);
    let quill = this.$refs.myQuillEditor.quill;
    if (response.url != null) {
        //获取光标所在位置
        let length = quill.getSelection().index;
        //插入图片
        quill.insertEmbed(length, 'image', response.url);
        //移动光标到图片后
        quill.setSelection(length + 1);
    }
},

效果图:

视频上传:

Vue-Quill-Editor 上传视频时输入对应的URL,会转换成 iframe 标签存储,所以不必更改默认设置,只需提供一个视频上传接口(如果需要实现点击直接上传效果,参考图片上传)。代码参考:https://www.cnblogs.com/1312mn/p/11233395.html

<el-dialog
    title="视频上传"
    :visible.sync="dialogVideoVisible"
    width="40%"
    :close-on-click-modal="false"
>
    <myVideo></myVideo>            //封装的组件
</el-dialog>
<template>
  <el-row :gutter="20">
    <el-col :span="24">
      <div class="videoArea">
        <el-upload
          class="avatar-uploader"
          action="http://localhost:8080/project/uploadVideo"
          :headers="myHeaders"
          :before-upload="beforeUploadVideo"
          :on-success="handleVideoSuccess"
          :on-progress="uploadVideoProcess"
          :show-file-list="false"
        >
          <video
            v-if="videoForm.showVideoPath != '' && !videoFlag"
            :src="videoForm.showVideoPath"
            controls
            width="400"
            height="240"
          >
            您的浏览器不支持视频播放
          </video>
          <i
            v-else-if="videoForm.showVideoPath == '' && !videoFlag"
            class="el-icon-plus avatar-uploader-icon"
          ></i>
          <!-- 进度条 -->
          <el-progress
            v-if="videoFlag == true"
            type="circle"
            :percentage="videoUploadPercent"
            style="margin-top: 7px"
          ></el-progress>
        </el-upload>
      </div>
    </el-col>
    <el-col :span="24">
      <div class="textArea">
        <p>
          <span>单次最多上传1个视频,大小不要超过50M,上传后返回的URL用于正文插入视频</span>
        </p>
        <p>
          <span v-if="videoForm.showVideoPath != ''">视频URL:
            <span class="urlArea">
              {{ videoForm.showVideoPath }}
            </span>
          </span>
        </p>
      </div>
    </el-col>
  </el-row>
</template>
<script>
export default {
  data() {
    return {
      //token
      myHeaders: { Authorization: localStorage.getItem("token") },
      //视频
      videoFlag: false,
      //是否显示进度条
      videoUploadPercent: "",
      //进度条的进度,
      isShowUploadVideo: false,
      //显示上传按钮
      videoForm: {
        showVideoPath: "",
      },
    };
  },
  methods: {
    //上传前回调
    beforeUploadVideo(file) {
      var fileSize = file.size / 1024 / 1024 < 50;
      if (
        [
          "video/mp4",
          "video/ogg",
          "video/flv",
          "video/avi",
          "video/wmv",
          "video/rmvb",
          "video/mov",
        ].indexOf(file.type) == -1
      ) {
        this.$message.error("请上传正确的视频格式");
        return false;
      }
      if (!fileSize) {
        this.$message.error("视频大小不能超过50MB");
        return false;
      }
      this.isShowUploadVideo = false;
    },
    //进度条
    uploadVideoProcess(event, file, fileList) {
      this.videoFlag = true;
      this.videoUploadPercent = file.percentage.toFixed(0) * 1;
    },
    //上传成功回调
    handleVideoSuccess(res, file) {
      this.isShowUploadVideo = true;
      this.videoFlag = false;
      this.videoUploadPercent = 0;
      if (200 == res.code) {
        this.videoForm.showVideoPath = res.url;
      } else {
        this.$message.error(res.msg);
      }
    },
  },
};

效果图:

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Element UI的vue-quill-editor富文本编辑器支持插入图片,但是默认的图片上传功能可能不能满足所有需求,需要进行自定义。 首先,在vue-quill-editor的配置中添加`imageHandler`方法,用于处理图片上传: ```javascript <template> <quill-editor v-model="content" :options="editorOption"></quill-editor> </template> <script> import { quillEditor } from 'vue-quill-editor' export default { components: { quillEditor }, data () { return { content: '', editorOption: { imageHandler: this.imageHandler // 添加imageHandler方法 } } }, methods: { imageHandler () { // 处理图片上传 } } } </script> ``` 然后,可以使用第三方上传组件(如`el-upload`)进行图片上传,上传完成后将图片地址返回给`quill-editor`。可以在`imageHandler`方法中实现该逻辑: ```javascript <template> <div> <el-upload class="upload-demo" :action="uploadUrl" :on-success="handleSuccess" :show-file-list="false" :headers="headers" ref="upload" > <el-button size="small" type="primary">上传图片</el-button> </el-upload> </div> </template> <script> import { quillEditor } from 'vue-quill-editor' import { mapGetters } from 'vuex' export default { components: { quillEditor }, data () { return { content: '', editorOption: { imageHandler: this.imageHandler }, uploadUrl: 'https://www.example.com/upload' // 图片上传地址 } }, computed: { ...mapGetters(['getToken']) // 获取token }, methods: { imageHandler () { const self = this const uploadImg = this.$refs.upload uploadImg.click() uploadImg.$refs.input.onchange = function () { const file = uploadImg.$refs.input.files[0] const formData = new FormData() formData.append('file', file) self.$axios.post(self.uploadUrl, formData, { headers: { 'Authorization': self.getToken // 设置token } }).then(res => { const url = res.data.url // 获取图片地址 const editor = self.$refs.editor.quill // 获取quill对象 const index = (editor.getSelection() || {}).index || editor.getLength() editor.insertEmbed(index, 'image', url) // 插入图片 }).catch(err => { console.log(err) }) } } } } </script> ``` 在这个例子中,使用了`el-upload`组件进行图片上传,上传完成后将图片地址返回给`quill-editor`。在`imageHandler`方法中,通过`this.$refs.editor.quill`获取到了`quill`对象,然后调用`insertEmbed`方法插入图片。 需要注意的是,由于`quill`对象是异步创建的,所以需要在`mounted`生命周期中获取到`quill`对象才能进行图片插入。可以使用`$nextTick`方法来确保获取到了`quill`对象: ```javascript <template> <quill-editor v-model="content" :options="editorOption" ref="editor"></quill-editor> </template> <script> import { quillEditor } from 'vue-quill-editor' export default { components: { quillEditor }, data () { return { content: '', editorOption: { imageHandler: this.imageHandler } } }, mounted () { this.$nextTick(() => { // 获取quill对象 const editor = this.$refs.editor.quill // 在quill对象中添加图片上传功能 editor.getModule('toolbar').addHandler('image', () => { this.$refs.upload.click() }) }) }, methods: { imageHandler () { // 处理图片上传 } } } </script> ``` 在这个例子中,通过`editor.getModule('toolbar').addHandler`方法,在`quill`对象中添加了一个`image`按钮,点击该按钮时触发了上传图片的逻辑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值