zoukankan      html  css  js  c++  java
  • vue-quill-editor 自定义图片上传和视频上传

    安装

    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;
          }
        },
        //上传视频
        uploadVideoTip(param){
           const formData = new FormData()
           formData.append('file', param.file)
           this.videoProgress = true;
           fetchUploadVideo(formData).then(response => {
                this.videoForm.showVideoPath = response.videoUrl;
           // 获取富文本
                let quill = this.$refs.myQuillEditor.quill
           // 在光标所在位置 插入视频
                quill.insertEmbed(this.indexVideo,'video', this.videoForm.showVideoPath)
                quill.setSelection(this.indexVideo + 1)
                this.videoProgress = false;
                this.videoFlag = 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)
            });
        },
      }
     
    // 隐藏图片上传表单
         <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="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="uploadVideoTip"
                    >
                      <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{
       100%;
    }
    .editerVideo_title{
      display: flex;
      height: 30px;
      line-height: 30px;
       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{
       100%;
      height: 120px;
    }
    .editerVideo_main_url{
       100%;
      height: 200px;
      line-height: 30px;
      display: flex;
      flex-direction: row;
      justify-content:flex-start;
      margin-top: 35px;
    }
    .avatar-uploader_video{
       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{
       800px;
      height:320px;
    }
    .quillWidth{
      800px;
      height:270px;
    }
     

    video.js

    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(value)
        // 添加video标签所需的属性
        node.setAttribute('controls', 'controls')
        node.setAttribute('type', 'video/mp4')
        node.setAttribute('src', this.sanitize(value))
        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) // eslint-disable-line import/no-named-as-default-member
      }
    
      static value (domNode) {
        return domNode.getAttribute('src')
      }
    
      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
    

      

     

     

  • 相关阅读:
    ERROR: do not initialise statics to false
    kernel defconfig
    python --- comment
    python --- for
    Xcode密钥没有备份或者证书过期,出现Valid Signing错误
    [iOS]XCODE5升级之路
    VirtualBOX 虚拟机安装 OS X 10.9 Mavericks 及 Xcode 5,本人X220亲测
    [下载] MultiBeast 6.2.1版,支持10.9 Mavericks。Mac上的驱动精灵,最简单安装驱动的方式。
    XCode 5资源文件不自动更新问题
    Microsoft Word 2010/2013 无法创建工作文件 请检查临时环境变量
  • 原文地址:https://www.cnblogs.com/nmxs/p/15324308.html
Copyright © 2011-2022 走看看