Vue中使用quill富文本编辑器(可上传本地图片,视频)

前言


需求需要实现富文本的功能,同时富文本中还可以上传视频和图片,选来选去最后决定了用这个富文本编辑器

官网:https://quilljs.com/

1、安装富文本编辑器

npm install vue-quill-editor --save

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);

3、在页面中的使用

(1)template中使用
 <div class="edit_container" style="width: 100%;height: 100%">
      <quill-editor
        v-model="content"
        ref="myQuillEditor"
        :options="editorOption"
        @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"
        @change="onEditorChange($event)">
      </quill-editor>
      <!-- 使用input 标签劫持原本视频上传事件,实现视频上传 -->
      <input type="file" accept="video/*" name="file" ref="uploadFileVideo" id="uploadFileVideo" @change="changevideo" style="opacity: 0; width: 0; height: 0;cursor: pointer">
      <!--使用input 标签劫持原本图片上传事件,实现图片上传-->
      <input type="file" name="file" id="uploadFileImg" ref="uploadFileImg" @change="changeImg" style="opacity: 0; width: 0; height: 0;cursor: pointer">
    </div>
(2)script 中引入
  import * as Quill from 'quill';  //引入编辑器
  //自定义quill编辑器的字体
  var fonts = ['Microsoft-YaHei', 'YouYuan',  'SimSun', 'SimHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif'];
  var Font = Quill.import('formats/font');
  Font.whitelist = fonts; //将字体加入到白名单
  Quill.register(Font, true);
  /*设置字体大小*/
  var Size = Quill.import('attributors/style/size');
  Size.whitelist = ['10px', '12px', '14px', '16px', '18px', '20px', '24px', false];
  Quill.register(Size, true);
(3)data 中定义
editorOption: {
         placeholder: '输入文本...',
         theme: 'snow', //主题
         modules: {
           imageResize: {   //添加图片拖拽上传,自定义大小(下面会详细介绍安装方法)
             displayStyles: {   //添加
               backgroundColor: 'black',
               border: 'none',
               color: 'white'
             },
             modules: ['Resize', 'DisplaySize', 'Toolbar']   //添加
           },
           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' }],             // 文本方向
               [{ 'size': ['10px', '12px', '14px', '16px', '18px', '20px', '24px', false] }], // 字体大小,false设置自定义大小
               [{ 'header': [1, 2, 3, 4, 5, 6, false] }],     //几级标题
               [{ 'color': [] }, { 'background': [] }],     // 字体颜色,字体背景颜色
               [{ 'font': fonts }],     //字体
               [{ 'align': [] }],    //对齐方式
               ['clean'],    //清除字体样式
               ['image', 'video']    //上传图片、上传视频
             ],
             handlers: {
               'video': function(val) {// 劫持原来的视频点击按钮事件
                 document.querySelector('#uploadFileVideo').click();
               },
               'image': function () {  // 劫持原来的图片点击按钮事件
                 document.querySelector('#uploadFileImg').click();
               }
             }
           }
         }
       }
(5)methods 中的方法
   methods: {
      getMountData() {},
      onEditorReady(editor) {},// 准备编辑器
      onEditorBlur() {}, // 失去焦点事件
      onEditorFocus() {}, // 获得焦点事件
      onEditorChange() {}, // 内容改变事件
      // 转码
      escapeStringHTML(str) {
        str = str.replace(/&lt;/g, '<');
        str = str.replace(/&gt;/g, '>');
        return str;
      },
      changeImg() {
        //上传图片到服务器
        //回调中调用  this.insertEle('image', data); 方法,插入图片到富文本
      }, //图片上传事件
      changevideo() {
          //上传视频到服务器
        //回调中调用  this.insertEle('video', data); 方法,插入图片到富文本
      },  //视频上传事件
      insertEle(type, url) {
          let quill = this.$refs.myQuillEditor.quill;
          let length = quill.getSelection().index;
          // 插入视频  response.data.url为服务器返回的图片地址
          if (type === 'video') {
            quill.insertEmbed(length, 'simpleVideo', {
              url,
              controls: 'controls',
              width: '100%',
              height: 'auto'
            });
          } else {
            quill.insertEmbed(length, type, url);
          }
          // 调整光标到最后
          quill.setSelection(length + 1);
        }
    }
(6)css 部分
  .ql-snow .ql-picker.ql-header .ql-picker-item::before {
    content: '文本';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
    content: '标题1';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
    content: '标题2';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
    content: '标题3';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
    content: '标题4';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
    content: '标题5';
  }
  .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
  .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
    content: '标题6';
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimSun]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimSun]::before {
    content: "宋体";
    font-family: "SimSun";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=SimHei]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=SimHei]::before {
    content: "黑体";
    font-family: "SimHei";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Microsoft-YaHei]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Microsoft-YaHei]::before {
    content: "微软雅黑";
    font-family: "Microsoft YaHei";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=YouYuan]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=YouYuan]::before {
    content: "幼圆";
    font-family: "YouYuan";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=KaiTi]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=KaiTi]::before {
    content: "楷体";
    font-family: "KaiTi";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=FangSong]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=FangSong]::before {
    content: "仿宋";
    font-family: "FangSong";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Arial]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Arial]::before {
    content: "Arial";
    font-family: "Arial";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=Times-New-Roman]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=Times-New-Roman]::before {
    content: "Times New Roman";
    font-family: "Times New Roman";
  }
  .ql-snow .ql-picker.ql-font .ql-picker-label[data-value=sans-serif]::before,
  .ql-snow .ql-picker.ql-font .ql-picker-item[data-value=sans-serif]::before {
    content: "sans-serif";
    font-family: "sans-serif";
  }

  .ql-font-SimSun {
    font-family: "SimSun";
  }
  .ql-font-SimHei {
    font-family: "SimHei";
  }
  .ql-font-YouYuan {
    font-family: "YouYuan";
  }
  .ql-font-Microsoft-YaHei {
    font-family: "Microsoft YaHei";
  }
  .ql-font-KaiTi {
    font-family: "KaiTi";
  }
  .ql-font-FangSong {
    font-family: "FangSong";
  }
  .ql-font-Arial {
    font-family: "Arial";
  }
  .ql-font-Times-New-Roman {
    font-family: "Times New Roman";
  }
  .ql-font-sans-serif {
    font-family: "sans-serif";
  }
  /*字体样式*/
  /*//默认的样式*/
  .ql-container {
    font-size:16px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='10px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='10px']::before {
    content: '10px';
    font-size: 10px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='12px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='12px']::before {
    content: '12px';
    font-size: 12px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before {
    content: '14px';
    font-size: 14px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before {
    content: '16px';
    font-size: 16px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='18px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='18px']::before {
    content: '18px';
    font-size: 18px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before {
    content: '20px';
    font-size: 20px;
  }
  .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='24px']::before,
  .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='24px']::before {
    content: '24px';
    font-size: 24px;
  }
  //自己添加自己需要的字体和样式

4、quill-image-resize-module的安装和使用

这个是quill的一个组件,可以对上传到富文本的图片进行调整,实用又方便。

(1)安装 quill-image-resize-module

npm install quill-image-resize-module --save

(2) script 引入
import ImageResize from 'quill-image-resize-module'  //添加
Quill.register('modules/imageResize', ImageResize)  //添加
(3) 配置editorOption.modules{}中添加以下代码(上面editorOption)为已经配置好的
  imageResize: {   //添加
                  displayStyles: {   //添加
                    backgroundColor: 'black',
                    border: 'none',
                    color: 'white'
                  },
                  modules: ['Resize', 'DisplaySize', 'Toolbar']   //添加
                }
(4) 配置build文件夹中的webpack.base.conf.js文件(不然会报错)
引入:var webpack = require('webpack');
然后在   module.exports中的最后加入下面的代码:
plugins: [
      new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js',
        'Quill': 'quill/dist/quill.js'
      })
    ]

5、上传视频自定义样式

(1) 新建 video.js
const BlockEmbed = Quill.import('blots/block/embed');
class VideoBlot extends BlockEmbed {
  static create (value) {
    let node = super.create();
    node.setAttribute('src', value.url);
    node.setAttribute('controls', value.controls);
    node.setAttribute('width', value.width);
    node.setAttribute('height', value.height);
    node.setAttribute('webkit-playsinline', true);
    node.setAttribute('playsinline', true);
    node.setAttribute('x5-playsinline', true);
    return node;
  }
  static value (node) {
    return {
      url: node.getAttribute('src'),
      controls: node.getAttribute('controls'),
      width: node.getAttribute('width'),
      height: node.getAttribute('height')
    };
  }
}
VideoBlot.blotName = 'simpleVideo';
VideoBlot.tagName = 'video';
export default VideoBlot;
(2) 组件中引入 video.js
  import VideoBlot from './video.js';
  Quill.register(VideoBlot);
  //使用在上面的insertEle()方法中,type 为 video 已经注明,这里就不写了

好了,到这里就全部配置完成(后台返回的图片和视频均为服务端地址)

最后附上一张照片

唯一的遗憾是没有太多时间去研究上传的视频的调整(持续加油!)

转载请注明

还请多多指教啦

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
vue2quill是一个基于Vue.jsQuill.js实现的富文本编辑器组件。它支持上传图片视频,但需要你自己实现上传的逻辑。 对于上传视频的实现,你可以使用一些常用的视频上传方案,比如通过后端接口实现文件上传使用第三方云存储服务等。在vue2quill,你需要做的就是通过配置参数来指定上传视频的接口地址或者上传视频的回调函数。 以下是一个使用vue2quill上传视频的示例代码: ``` <template> <div> <quill-editor v-model="content" :options="editorOption" @image-added="onImageAdded" @video-added="onVideoAdded"></quill-editor> </div> </template> <script> import QuillEditor from 'vue-quill-editor' export default { components: { QuillEditor }, data () { return { content: '', editorOption: { modules: { toolbar: [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'], // remove formatting button ['link', 'image', 'video'] // link and image, video ] }, placeholder: '请输入正文', theme: 'snow' } } }, methods: { onImageAdded (file, callback) { // 处理图片上传 let formData = new FormData() formData.append('file', file) axios.post('/upload/image', formData) .then(res => { callback(res.data.url) }) }, onVideoAdded (file, callback) { // 处理视频上传 let formData = new FormData() formData.append('file', file) axios.post('/upload/video', formData) .then(res => { callback(res.data.url) }) } } } </script> ``` 在上述代码,我们通过配置QuillEditor组件的options参数来设置富文本编辑器的选项,包括工具栏、占位符等。在onImageAdded和onVideoAdded回调函数,我们可以处理上传图片上传视频的逻辑,并通过callback函数将上传后的图片视频的地址返回给富文本编辑器组件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值