vue-quill-editor 自定义图片上传和视频上传(阿里云oss上传 );video替换iframe标签

46 篇文章 0 订阅
1 篇文章 0 订阅

这个编辑器,可支持上传图片、视频链接或视频,

插入视频功能做了一下改进;

图片和视频是上传到阿里云oss,拿到oss地址后 插到编辑器里回显的;

注意:

上传视频后,视频回显标签是用iframe包裹的,在手机端可能会有显示问题,显示页面获取接口video标签替换 iframe 标签:

        this.details.articleContent=this.details.articleContent.replace('<iframe', `<video controls="" autoplay="" style="width: 100%;"`).replace('</iframe>', '</video>')

 

安装

npm install vue-quill-editor --save

在main.js  引入

import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

// 页面引入

import { quillEditor,Quill } from 'vue-quill-editor'
import Video from '../../../utils/video'
Quill.register(Video, true)

// 配置项

  editorOption: {
         modules:{
             toolbar:{
                container: [
                    ['bold', 'italic', 'underline', 'strike'], //加粗,斜体,下划线,删除线
                    [{ 'header': 1 }, { 'header': 2}], // 标题,键值对的形式;1、2表示字体大小
                    [{'list': 'ordered'}, {'list': 'bullet'}], //列表
                    [{ 'script': 'sub'}, {'script': 'super' }], // 上下标
                    [{ 'indent': '-1'}, {'indent': '+1'}], // 缩进
                    [{'direction': 'rtl' }], // 文本方向
                    ['clean'], //清除字体样式
                    ['image', 'video'] //上传图片、上传视频
                ],
                handlers: {
                  'video':(val)=>{
                    // 覆盖默认的上传视频

            this.onVideo();

                  },
                  'image':(value)=>{
            // 覆盖默认的图片上传
            // 获取光标所在的位置
                    var range = this.$refs.myQuillEditor.quill.getSelection();
                    if (range == null) {
                      this.indexVideo = 0;
                    } else {
                      this.indexVideo = range.index;
                    }
            // 点击隐藏的上传表单
                    if (value) {
                       document.querySelector('.avataruploaderTip input').click()
                    } else {
                      this.quill.format('image', false)
                    }
                  }
                }
             }
         },
         placeholder:'请输入'
    },
   // 相关变量

   indexVideo:0,
   videoUrl:'',
   videoTab:{
     tabUrl:true,
     tabUpd:false
   },
   videoProgress:false,
 


  // 声明组件

  components: {
     quillEditor
  },

// 富文本相关
    onVideo(){
        this.videoFlag = true;
         //当编辑器中没有输入文本时,这里获取到的 range 为 null   获取光标位置
        var range = this.$refs.myQuillEditor.quill.getSelection();
        if (range == null) {
          this.indexVideo = 0;
        } else {
          this.indexVideo = range.index;
        }
    },
    onVideoTab(val){  // 链接与视频上传 tab切换
      if(val == 1){
        this.videoTab.tabUrl = true;
        this.videoTab.tabUpd = false;
      }else{
        this.videoTab.tabUpd = true;
        this.videoTab.tabUrl = false;
      }
    },

  // 上传之前请求后台接口 拿上传oss需要的参数

            async beforeAvatarUploadTwo(file) {

                let that = this

                this.uillUpdateImg = true

                this.videoFlag = false

                await http.get("/photo/fetchStsCredentials", {})

                    .then(function (res) {

                        that.accessKeyId= res.data.accessKey;

                        that.accessKeySecret = res.data.accessKeySecret;

                        that.securityToken = res.data.securityToken

                    })

                    .catch(function (err) {

                        console.log("连接失败" + err);

                    });

            },

//上传文件到阿里云,返回数据,拿到url oss地址 

 uploadAvatarTwo(options) {

                let that = this

                let client = new OSS({

                    region: "oss-cn-qingdao",

                    accessKeyId: that.accessKeyId1,

                    accessKeySecret: that.accessKeySecret1,

                    stsToken: that.securityToken,

                    bucket: "medai",

                });

                let file = options.file; // 拿到 file

                let fileName = file.name.substr(0, file.name.lastIndexOf('.'))

                let date = new Date().getTime()

                let fileNames = `${date}_${fileName}`

                client.put(fileNames, file,).then(res => {

                    if (res.res.statusCode === 200) {

                        console.log(res);

                        options.onSuccess(res)

                    } else {

                        options.onError("上传失败")

                    }

                })

            },

  

// 上传视频成功回调

            upVideoUrl(res) {

                console.log(res);

                res.url?this.videoUrl=res.url: this.uillUpdateImg = true

                if (this.videoUrl) {

// 获取富文本

                    let quill = this.$refs.content.quill

 // 在光标所在位置 插入视频

                    quill.insertEmbed(this.indexVideo, 'video', this.videoUrl)

                    quill.setSelection(this.indexVideo + 1)

                    this.videoFlag = false;

                    this.videoUrl=''

                } else {

                    this.$message({

                        message: '请填写视频链接',

                        type: 'warning'

                    });

                }

                this.uillUpdateImg = false

            },


    // 上传图片链接
    upVideoUrl(){
      if(this.videoUrl){
         let quill = this.$refs.myQuillEditor.quill
         quill.insertEmbed(this.indexVideo,'video', this.videoUrl)
         quill.setSelection(this.indexVideo + 1)
         this.videoFlag = false;
      }else{
        this.$message({
            message: '请填写视频链接',
            type: 'warning'
        });
      }
    },
  // 图片上传
    uploadImgTip(param){
       const formData = new FormData()
       formData.append('file', param.file)
       fetchImg(formData).then(response => {
          let url = response.imgUrl
           let quill = this.$refs.myQuillEditor.quill
      // 插入图片链接
           quill.insertEmbed(this.indexVideo, 'image', url)
           quill.setSelection(this.indexVideo + 1)
        });
    },
  }
 
// 隐藏图片上传表单 HTML

     <el-upload  
        class="avataruploaderTip"
        ref="uploadtip"
        :limit="999"
        action="#"
        :show-file-list="false"
        :http-request="uploadImgTip"
        >
      </el-upload>
// 视频上传弹出框


  <el-dialog
      title="视频上传"
      :visible.sync="videoFlag"
      :close-on-click-modal="false"
      class="editerV"
      width="500px">
      <div class="editerVideo">
         <div class="editerVideo_title">
           <div :class="['editerVideo_title_item',videoTab.tabUrl?'editerVideo_title_act':''] " @click="onVideoTab(1)">添加链接</div>
           <div :class="['editerVideo_title_item',videoTab.tabUpd?'editerVideo_title_act':''] " @click="onVideoTab(2)">上传视频</div>
         </div>
         <div class="editerVideo_main">
            <div class="editerVideo_main_url" v-if="videoTab.tabUrl">
              <div>视频地址:</div>
              <el-input size="small" v-model="videoUrl" style="width:300px"></el-input>
              <el-button  type="primary"  style=" margin-left:10px;  height:30px" @click="upVideoUrl" size="small" >添加</el-button>
            </div>
            <div v-if="videoTab.tabUpd">
                <div v-if="videoProgress" class="videoProgress">视频上传中,请耐心等待!</div>
                <el-upload
                  v-else
                  class="avatar-uploader_video"
                  :limit=1
                  action="#"
                  :show-file-list="false"
                  :http-request="uploadAvatarTwo"

                  :before-upload="beforeAvatarUploadTwo"

                    :on-success="upVideoUrl"
                >
                  <i class="el-icon-plus avatar-uploader-videoiocn"></i>
                </el-upload>
               
            </div>
         </div>
      </div>
  </el-dialog>


// 视频上传组件
.editerV /deep/ .el-dialog__body{
  padding: 0px 20px 20px 20px;
}
.editerVideo{
  width: 100%;
}
.editerVideo_title{
  display: flex;
  height: 30px;
  line-height: 30px;
  width: 100%;
  color: #1f2f3d;
  font-weight: bold;
  justify-content: flex-start;
  border-bottom: 2px solid #DCDFE6;
}
.editerVideo_title_act{
  color: #409eff;
  border-bottom: 2px solid #409eff;
  margin-bottom: -2px;
}
.editerVideo_title_item{
  margin-right: 10px;
}
.editerVideo_main{
  width: 100%;
  height: 120px;
}
.editerVideo_main_url{
  width: 100%;
  height: 200px;
  line-height: 30px;
  display: flex;
  flex-direction: row;
  justify-content:flex-start;
  margin-top: 35px;
}
.avatar-uploader_video{
  width: 100px;
  height: 100px;
  border: 1px solid #D9D9D9;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 30px;
}
.avatar-uploader-videoiocn {
  font-size: 28px;
  color: #D9D9D9;
  line-height: 90px;
  text-align: center;
}
.videoProgress{
  margin-top: 30px;
}
.quillWidthmain{
  width: 800px;
  height:320px;
}
.quillWidth{
  width:800px;
  height:270px;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值