zoukankan      html  css  js  c++  java
  • 第三篇. vue中使用vue-quill-editor富文本插件,图片上传,视频上传

    1.安装
    vue-quill-editor github地址:https://github.com/surmon-china/vue-quill-editor
    官方文档地址:https://www.npmjs.com/package/vue-quill-editor
    基于Quill、适用于Vue2的富文本编辑器,支持服务端渲染和单页应用
    
    npm install vue-quill-editor --save
    
    安装图片拖动和变化大小的插件,需要在vue.config.js引入webpack中配置 不配置会出错,具体链接(https://github.com/kensnyder/quill-image-resize-module/issues/54)
    plugins: [
        new webpack.ProvidePlugin({
            'window.Quill': 'quill/dist/quill.js',
            'Quill': 'quill/dist/quill.js',
        }),
    ]
    
    2.局部引入
    import Vue from 'vue'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import { quillEditor } from 'vue-quill-editor'
    import Quill from 'quill'
    import { ImageDrop } from 'quill-image-drop-module'  // 图片拖动插件
    import ImageResize from 'quill-image-resize-module'  // 图片设置大小插件
    Quill.register('modules/imageDrop', ImageDrop)       // 图片拖动插件
    Quill.register('modules/imageResize', ImageResize)   // 图片设置大小插件
    // 鼠标移入显示title文字
    import { addQuillTitle } from '@/assets/quill-title.js'
    Vue.use(quillEditor)
    // 图片上传接口
    import { richTextImgUpload } from '@/api/uploadFIle'
    
    3.工具栏配置
    // 工具栏配置
    const toolbarOptions = [
      ['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: ['small', false, 'large', 'huge'] }], // 字体大小
      [{ header: [1, 2, 3, 4, 5, 6, false] }], // 几级标题
    
      [{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色
      [{ font: [] }], // 字体
      [{ align: [] }], // 对齐方式
    
      ['clean'], // 清除字体样式
      ['image', 'video'] // 上传图片、上传视频
    ]
    /* 富文本编辑图片上传配置*/
    const uploadConfig = {
      action: '', // 必填参数 图片上传地址
      methods: 'POST', // 必填参数 图片上传方式
      token: '', // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage
      name: 'img', // 必填参数 文件的参数名
      size: 500, // 可选参数   图片大小,单位为Kb, 1M = 1024Kb
      accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可选 可上传的图片格式
    }
    
    4.data中初始化配置
    data() {
        return {
          content: '',
          videoOrimg:true,
          editorOption: {
            placeholder: '请输入...',
            modules: {
              imageResize: {}, //图片拖动设置大小
              imageDrop: true, // 图片拖动
              toolbar: {
                container: toolbarOptions, //工具栏
                handlers: {
                  image: (value) => {
                    if (value) {
                      // 这是是为了获取你当前点击的那个富文本框
                      this.videoOrimg = true
                      document.querySelectorAll('.upload-demo input')[0].click()
                    } else {
                      this.quill.format('image', false)
                    }
                  },
                  video: (value) => {
                    if (value) {
                      // 这是是为了获取你当前点击的那个富文本框
                      this.videoOrimg = false
                      document.querySelectorAll('.upload-demo input')[0].click()
                    } else {
                      this.quill.format('image', false)
                    }
                  }
                }
              }
            },
            theme: 'snow'
          }
        }
      },
    
    5.模板中使用
    <template>
      <div>
        <el-upload
          class="upload-demo"
          action="#"
          name="file"
          :http-request="requestUpload"
          :before-upload="beforeAvatarUpload"
          :on-success="handleSuccess"
          multiple
        />
        <quill-editor ref="toref" v-model="content" :options="editorOption"  />
      </div>
    </template>
    
    6.图片上传(视频上传同理)
    因为是前后端分离的,富文本上传图片要单独上传,在content中替换为后端返回图片地址。
     methods: {
        // 覆盖默认的上传行为
        requestUpload(params) {
          const formData = new FormData()
          formData.append('img', params.file)
           // 图片
          if(this.videoOrimg){
            richTextImgUpload(formData).then((res) => {
              params.onSuccess(res)
            })
          }else{
            richTextVideoUpload(formData).then((res) => {
              params.onSuccess(res)
            })
          }
          
        },
        // 判断图片后缀
        beforeAvatarUpload(file) {
          console.log(file,'dasda')
          const isJPG = file.type === 'image/jpeg' || 'image/png'
          const isVideo = file.type === 'video/mp4'
          const isLt2M = file.size / 1024 / 1024 < 10
          // 图片
          if(this.videoOrimg){
            if (!isJPG) {
              this.$message.error('上传图片只能是 JPG , PNG格式!')
            }
            if (!isLt2M) {
              this.$message.error('上传图片大小不能超过 10MB!')
            }
             return isJPG && isLt2M
          }else{
              if(!isVideo){
                this.$message.error('上传视频只能是 MP4格式!')
              }
              return isVideo
          }
         
        },
        // 上传成功
        handleSuccess(res, file) {
          if (res.error == 0) {
            // 动态添加 ref  通过 eval () 去执行
            const toeval = this.$refs.toref.quill
            // eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
            // 获取光标所在位置
            const length = toeval.selection.savedRange.index
            // 插入图片,res为服务器返回的图片链接地址
             // 图片
          if(this.videoOrimg){
            toeval.insertEmbed(
              length,
              'image',
              process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
            )
          }else{
            toeval.insertEmbed(
              length,
              'video',
              process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
            )
          }
            // 调整光标到最后
            toeval.setSelection(length + 1)
          }
        },
        // 将内容上传给父组件
        postContent() {
          this.$emit('getContent', this.content)
        },
      },
    
    7.quill-title.js内容
    const titleConfig = {
        'ql-bold':'加粗',
        'ql-color':'颜色',
        'ql-font':'字体',
        'ql-code':'插入代码',
        'ql-italic':'斜体',
        'ql-link':'添加链接',
        'ql-background':'背景颜色',
        'ql-size':'字体大小',
        'ql-strike':'删除线',
        'ql-script':'上标/下标',
        'ql-underline':'下划线',
        'ql-blockquote':'引用',
        'ql-header':'标题',
        'ql-indent':'缩进',
        'ql-list':'列表',
        'ql-align':'文本对齐',
        'ql-direction':'文本方向',
        'ql-code-block':'代码块',
        'ql-formula':'公式',
        'ql-image':'图片',
        'ql-video':'视频',
        'ql-clean':'清除字体样式'
      };
       
      export function addQuillTitle(){
        const oToolBar = document.querySelector('.ql-toolbar'),
              aButton = oToolBar.querySelectorAll('button'),
              aSelect =  oToolBar.querySelectorAll('select');
        aButton.forEach(function(item){
          if(item.className === 'ql-script'){
            item.value === 'sub' ? item.title = '下标': item.title = '上标';
          }else if(item.className === 'ql-indent'){
            item.value === '+1' ? item.title ='向右缩进': item.title ='向左缩进';
          }else{
            item.title = titleConfig[item.classList[0]];
          }
        });
        aSelect.forEach(function(item){
          item.parentNode.title = titleConfig[item.classList[0]];
        });
      }
    
    8.完整代码
    <template>
      <div>
        <el-upload
          class="upload-demo"
          action="#"
          name="file"
          :http-request="requestUpload"
          :before-upload="beforeAvatarUpload"
          :on-success="handleSuccess"
          multiple
        />
        <quill-editor ref="toref" v-model="content" :options="editorOption"  />
      </div>
    </template>
    
    <script>
    import Vue from 'vue'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    import { quillEditor } from 'vue-quill-editor'
    import Quill from 'quill'
    import { ImageDrop } from 'quill-image-drop-module'  // 图片拖动插件
    import ImageResize from 'quill-image-resize-module'  // 图片设置大小插件
    Quill.register('modules/imageDrop', ImageDrop)       // 图片拖动插件
    Quill.register('modules/imageResize', ImageResize)   // 图片设置大小插件
    // 鼠标移入显示title文字
    import { addQuillTitle } from '@/assets/quill-title.js'
    Vue.use(quillEditor)
    // 图片上传接口
    import { richTextImgUpload, richTextVideoUpload } from '@/api/uploadFIle'
    // 工具栏配置
    const toolbarOptions = [
      ['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: ['small', false, 'large', 'huge'] }], // 字体大小
      [{ header: [1, 2, 3, 4, 5, 6, false] }], // 几级标题
    
      [{ color: [] }, { background: [] }], // 字体颜色,字体背景颜色
      [{ font: [] }], // 字体
      [{ align: [] }], // 对齐方式
    
      ['clean'], // 清除字体样式
      ['image', 'video'] // 上传图片、上传视频
    ]
    /* 富文本编辑图片上传配置*/
    const uploadConfig = {
      action: '', // 必填参数 图片上传地址
      methods: 'POST', // 必填参数 图片上传方式
      token: '', // 可选参数 如果需要token验证,假设你的token有存放在sessionStorage
      name: 'img', // 必填参数 文件的参数名
      size: 500, // 可选参数   图片大小,单位为Kb, 1M = 1024Kb
      accept: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' // 可选 可上传的图片格式
    }
    export default {
      components: {
        quillEditor
      },
      props: {
        contents:String,
        default:''
      },
      data() {
        return {
          content: '',
          videoOrimg:true,
          editorOption: {
            placeholder: '请输入...',
            modules: {
              imageResize: {}, //图片拖动设置大小
              imageDrop: true, // 图片拖动
              toolbar: {
                container: toolbarOptions, //工具栏
                handlers: {
                  image: (value) => {
                    if (value) {
                      // 这是是为了获取你当前点击的那个富文本框
                      this.videoOrimg = true
                      document.querySelectorAll('.upload-demo input')[0].click()
                    } else {
                      this.quill.format('image', false)
                    }
                  },
                  video: (value) => {
                    if (value) {
                      // 这是是为了获取你当前点击的那个富文本框
                      this.videoOrimg = false
                      document.querySelectorAll('.upload-demo input')[0].click()
                    } else {
                      this.quill.format('image', false)
                    }
                  }
                }
              }
            },
            theme: 'snow'
          }
        }
      },
      mounted() {
        addQuillTitle()
      },
      methods: {
        // 覆盖默认的上传行为
        requestUpload(params) {
          const formData = new FormData()
          formData.append('img', params.file)
           // 图片
          if(this.videoOrimg){
            richTextImgUpload(formData).then((res) => {
              params.onSuccess(res)
            })
          }else{
            richTextVideoUpload(formData).then((res) => {
              params.onSuccess(res)
            })
          }
          
        },
        // 判断图片后缀
        beforeAvatarUpload(file) {
          console.log(file,'dasda')
          const isJPG = file.type === 'image/jpeg' || 'image/png'
          const isVideo = file.type === 'video/mp4'
          const isLt2M = file.size / 1024 / 1024 < 10
          // 图片
          if(this.videoOrimg){
            if (!isJPG) {
              this.$message.error('上传图片只能是 JPG , PNG格式!')
            }
            if (!isLt2M) {
              this.$message.error('上传图片大小不能超过 10MB!')
            }
             return isJPG && isLt2M
          }else{
              if(!isVideo){
                this.$message.error('上传视频只能是 MP4格式!')
              }
              return isVideo
          }
        },
        // 上传成功
        handleSuccess(res, file) {
          if (res.error == 0) {
            // 动态添加 ref  通过 eval () 去执行
            const toeval = this.$refs.toref.quill
            // eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
            // 获取光标所在位置
            const length = toeval.selection.savedRange.index
            // 插入图片,res为服务器返回的图片链接地址
             // 图片
          if(this.videoOrimg){
            toeval.insertEmbed(
              length,
              'image',
              process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
            )
          }else{
            toeval.insertEmbed(
              length,
              'video',
              process.env.VUE_APP_BASE_API_ORIGIN + res.data.imgscr
            )
          }
            // 调整光标到最后
            toeval.setSelection(length + 1)
          }
        },
        // 将内容上传给父组件
        postContent() {
          this.$emit('getContent', this.content)
        },
      },
      watch: {
        contents:{
            immediate: true,    // 这句重要
            handler (val) {
                this.content = this.contents
            }
        }
      }
    }
    </script>
    
    <style scoped>
    .upload-demo {
      display: none;
    }
    </style>
    
    
    9.预览

  • 相关阅读:
    nginx 下 bootstrap fa 字体异常问题
    centos7 & mysql
    ssh authentication魔鬼细节--.ssh文件夹权限
    python self introspection
    __getattr__ 与动态属性
    dict.items vs six.iteritems
    django ATOMIC_REQUESTS
    HDU 4309 Seikimatsu Occult Tonneru (状压 + 网络流)
    UVaLive 4064 Magnetic Train Tracks (极角排序)
    UVa 11645 Bits (暴力+组合数学)
  • 原文地址:https://www.cnblogs.com/Ananiah/p/14489991.html
Copyright © 2011-2022 走看看