安装

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="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="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{
  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;
}
 

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

  

vue-quill-editor 自定义图片上传和视频上传的更多相关文章

  1. vue quill editor输入文字出现首字母的问题

    当使用vue quill editor输入中文时,第一个中文的汉语拼音第一个字母会显示如图. 解决的办法就是升级vue quill editor js文件的版本,目前的我升级之后ok的版本是 < ...

  2. 大文件上传-大视频上传,T级别的,求解决方案

    第一点:Java代码实现文件上传 FormFile file = manform.getFile(); String newfileName = null; String newpathname =  ...

  3. Vue+Element UI 实现视频上传

    一.前言 项目中需要提供一个视频介绍,使用户能够快速.方便的了解如何使用产品以及注意事项. 前台使用Vue+Element UI中的el-upload组件实现视频上传及进度条展示,后台提供视频上传AP ...

  4. SpringBoot 整合文件上传 elment Ui 上传组件

    SpringBoot 整合文件上传 elment Ui 上传组件 本文章记录 自己学习使用 侵权必删! 前端代码 博主最近在学 elment Ui 所以 前端使用 elmentUi 的 upload ...

  5. vue项目富文本编辑器vue-quill-editor之自定义图片上传

    使用富文本编辑器的第一步肯定是先安装依赖 npm i vue-quill-editor 1.如果按照官网富文本编辑器中的图片上传是将图片转为base64格式的,如果需要上传图片到自己的服务器,需要修改 ...

  6. CKEditor5 + vue2.0 自定义图片上传、highlight、字体等用法

    因业务需求,要在 vue2.0 的项目里使用富文本编辑器,经过调研多个编辑器,CKEditor5 支持 vue,遂采用.因 CKEditor5 文档比较少,此处记录下引用和一些基本用法. CKEdit ...

  7. rails使用bootstrap3-wysiwyg可视化编辑器并实现自定义图片上传插入功能

    之前在rails开发中使用了ckeditor作为可视化编辑器,不过感觉ckeditor过于庞大,有很多不需要的功能,而且图片上传功能不好控制不同用户可以互相删除图片,感觉很不好.于是考虑更改可视化编辑 ...

  8. ueditor 百度编辑器 自定义图片上传路径和格式化上传文件名

    今天项目中需要自定义图片上传的保存路径,并且不需要按照日期自动创建存储文件夹和文件名,我的ueditor版本是1.3.6.下面记录一下我配置成功的方法,如果有什么不对的地方欢迎指出,共同学习: 1:我 ...

  9. vue+element-ui中的图片获取与上传

    vue+element-ui中的图片获取与上传 工作上接触了一下图片的处理,图片的格式是文件流, 记录如下. 请求图片 请求图片的时候,带上{ responseType: 'blob' }, 否则图片 ...

  10. vue实现PC端调用摄像头拍照人脸录入、移动端调用手机前置摄像头人脸录入、及图片旋转矫正、压缩上传base64格式/文件格式

    进入正题 1. PC端调用摄像头拍照上传base64格式到后台,这个没什么花里胡哨的骚操作,直接看代码 (canvas + video) <template> <div> &l ...

随机推荐

  1. 安装 MinGW-w64

    简介 MinGW-w64 是 MinGW 项目的 64 位版本.MinGW(Minimalist GNU for Windows)是 GCC 编译套件和 GNU Binutils 移植到 Window ...

  2. chrome.tabs.sendMessage和chrome.runtime.sendMessage的用法及区别

    在 Chrome 扩展开发中,chrome.tabs.sendMessage 和 chrome.runtime.sendMessage 是用于不同目的的消息发送 API,它们的主要区别在于消息的目标对 ...

  3. 阿里云CTF and 其他

    RE复现 login_system 这个函数就是判断username,点进去发现是线性方程,用z3解 from z3 import * s=Solver() a=[0]*16 for i in ran ...

  4. C#设计模式入门实战教程

    什么是设计模式 设计模式是对面向对象设计中反复出现的问题的解决方案.它们提供了被反复使用.多数人知晓的.经过分类编目的代码设计经验总结. 设计模式的作用 提高代码的可重用性:通过定义一套标准的解决方案 ...

  5. linux 上抓包

    #tcpdump -i mgmt0 -nn -s0 -v port 8001 capture IPv6 ping packets #tcpdump ip6 -i nic0 -nn -s0 and ic ...

  6. CSS – 实战 Color

    前言 之前 W3Schools 学习笔记 (1) 也记入过 Color, 这篇整理一下在网页开发中, 颜色是如果被处理的. 网页都有什么颜色? 网页篇幅最大的颜色, 通常是来自图片, 不管是背景图, ...

  7. SQL Server 冗余维护

    介绍 冗余是维护的魔鬼, 是性能优化的天使 常见的冗余有 1. computed column 2. principal 的识别字段 3. cross computed 4. cascade soft ...

  8. C++ STL queue容器——队列

    queue容器 基本概念 queue是一种**先进先出的数据结构,它有两个出口,queue容器允许从一端新增元素,从另一端移除元素. queue容器没有迭代器,所有元素进出都必须符合"先进先 ...

  9. AD域下,没有登录服务器处理登录请求

    原因: IP地址配置有问题 或者 DNS : 解决办法: 重新设置 IP地址 和 DNS : 此案例中, 切换到 test 账户(域管理员)后发现 , 未配置 IP地址 和 DNS :

  10. iOS中MJExtension使用详解

    iOS开发中MVC模式最为常见,M代表模型,字典转成模型数据可以简化很多操作,下面我们说一下具体用法. 1.将字典转换成模型对象,模型中的属性名和responseObject字典中的字段名一致,我们得 ...