• vue中使用vuequilleditor富文本编辑器:自定义行高、选中后工具栏初始化


    1、引入组件

    <quill-editor
          ref="myQuillEditor"
          v-model="content"
          class="editor ql-editor"
          :options="editorOption"
          @blur="onEditorBlur($event)"
          @focus="onEditorFocus($event)"
          @change="onEditorChange($event)"
          @ready="ready($event)"
        />
    // 工具栏配置
    import { quillEditor } from 'vue-quill-editor'
    import { Uploads } from '@/api/hpms/qiniu'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'

    2、设置行高

    //lineHeight.js
    import Quill from "quill";
    const Parchment = Quill.import("parchment");
    class lineHeightAttributor extends Parchment.Attributor.Style { }
    const lineHeightStyle = new lineHeightAttributor("lineHeight", "line-height", {
      scope: Parchment.Scope.INLINE, whitelist: ["1", "2", "3", "4", "5"]
    });
    
    export { lineHeightStyle };
    import { lineHeightStyle } from "./lineHeight";
    ready() {
          Quill.register({ "formats/lineHeight": lineHeightStyle }, true)
        },
    editorOption: {
            placeholder: '您想说点什么?',
            theme: 'snow', // or 'bubble'
            modules: {
    
              toolbar: {
                container: toolbarOptions,
                // container: "#toolbar",
                handlers: {
                  lineHeight: (value) => {                 
                    if (value) {
                      const quill = this.$refs.myQuillEditor.quill
                      quill.format("lineHeight", value);
                    }
                  }
       
                }
              }
            }
          },

    3、行高样式

    .ql-snow .ql-picker.ql-lineHeight .ql-picker-label::before {
      content: "行高";
    }
    
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1"]::before {
      content: "行高1";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.5"]::before,
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.5"]::before {
      content: "行高1.5";
    }
    
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.75"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.75"]::before {
      content: "行高1.75";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="2"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="2"]::before {
      content: "行高2";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="3"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="3"]::before {
      content: "行高3";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="4"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="4"]::before {
      content: "行高4";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="5"]::before ,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="5"]::before{
      content: "行高5";
    }
    .ql-snow .ql-picker.ql-lineHeight {
       70px;
    }

    4、效果图

    5、完整代码

    <template>
      <div>
        <!-- 图片上传组件辅助-->
        <el-upload
          v-show="false"
          class="avatar-uploader"
          action="/bmms/web-bm/file"
          name="img"
          accept=".jpg, .png"
          :show-file-list="false"
          :on-change="handleChange"
          :http-request="httpRequest"
          :before-upload="beforeUpload"
        />
        <quill-editor
          ref="myQuillEditor"
          v-model="content"
          class="editor ql-editor"
          :options="editorOption"
          @blur="onEditorBlur($event)"
          @focus="onEditorFocus($event)"
          @change="onEditorChange($event)"
          @ready="ready($event)"
        />
      </div>
    </template>
    <script>
    // 工具栏配置
    import { quillEditor } from 'vue-quill-editor'
    import { Uploads } from '@/api/hpms/qiniu'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    
    import ImageResize from 'quill-image-resize-module'
    import * as Quill from 'quill'
    import { lineHeightStyle } from "./lineHeight";
    var Size = Quill.import('attributors/style/size')
    Size.whitelist = ['10px', '12px', '14px', '16px', '18px', '20px', '30px', '32px', '38px', '48px', '64px'] // 引入编辑器
    Quill.register(Size, true)
    Quill.register('modules/imageResize', ImageResize)
    
    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' }], // 缩进
      [{ size: Size.whitelist }],
      [{ 'align': [] }],
      [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
      [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
    
      ['clean'], // 清除文本格式
      [{ lineHeight: lineHeightStyle.whitelist }], // 对齐方式
      ['image'] // 链接、图片
    ]
    const toolbarTips = [
      { Choice: '.ql-bold', title: '加粗' },
      { Choice: '.ql-italic', title: '倾斜' },
      { Choice: '.ql-underline', title: '下划线' },
      { Choice: '.ql-header', title: '段落格式' },
      { Choice: '.ql-strike', title: '删除线' },
      { Choice: '.ql-blockquote', title: '块引用' },
      { Choice: '.ql-code-block', title: '插入代码段' },
      { Choice: '.ql-size', title: '字体大小' },
      { Choice: '.ql-list[value="ordered"]', title: '编号列表' },
      { Choice: '.ql-list[value="bullet"]', title: '项目列表' },
      { Choice: '.ql-header[value="1"]', title: 'h1' },
      { Choice: '.ql-header[value="2"]', title: 'h2' },
      { Choice: '.ql-align', title: '对齐方式' },
      { Choice: '.ql-color', title: '字体颜色' },
      { Choice: '.ql-background', title: '背景颜色' },
      { Choice: '.ql-image', title: '图像' },
      { Choice: '.ql-video', title: '视频' },
      { Choice: '.ql-link', title: '添加链接' },
      { Choice: '.ql-formula', title: '插入公式' },
      { Choice: '.ql-clean', title: '清除格式' },
      { Choice: '.ql-lineHeight', title: '设置行高' },
      { Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
      { Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
      { Choice: '.ql-header .ql-picker-label', title: '标题大小' },
      { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '标题一' },
      { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '标题二' },
      { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '标题三' },
      { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '标题四' },
      { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '标题五' },
      { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '标题六' },
      { Choice: '.ql-header .ql-picker-item:last-child', title: '标准' },
      { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小号' },
      { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大号' },
      { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
      { Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '标准' },
      { Choice: '.ql-align .ql-picker-item:first-child', title: '居左对齐' },
      { Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
      { Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
      { Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
    ]
    export default {
      components: {
        quillEditor
      },
      props: {
        /* 编辑器的内容 */
        value: {
          type: String,
          default: () => {}
        },
        /* 图片大小 */
        maxSize: {
          type: Number,
          default: 4000 // kb
        }
      },
    
      data () {
        return {
          params: {
            token: '',
            FileName: ''
          },
          content: this.value,
          quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
          editorOption: {
            placeholder: '您想说点什么?',
            theme: 'snow', // or 'bubble'
            modules: {
              imageResize: {
                displayStyles: {
                  backgroundColor: 'black',
                  border: 'none',
                  color: 'white'
                },
                modules: ['Resize', 'DisplaySize', 'Toolbar']
              },
              toolbar: {
                container: toolbarOptions,
                // container: "#toolbar",
                handlers: {
                  image: function (value) {
                    if (value) {
                      // 触发input框选择图片文件
                      document.querySelector('.avatar-uploader input').click()
                    } else {
                      this.quill.format('image', false)
                    }
                  },
                  lineHeight: (value) => {                 
                    if (value) {
                      const quill = this.$refs.myQuillEditor.quill
                      quill.format("lineHeight", value);
                    }
                  }
                  // link: function(value) {
                  //   if (value) {
                  //     var href = prompt('请输入url');
                  //     this.quill.format("link", href);
                  //   } else {
                  //     this.quill.format("link", false);
                  //   }
                  // },
                }
              }
            }
          },
          serverUrl: this.UploadFile(), // 这里写你要上传的图片服务器地址
          header: {
            // token: sessionStorage.token
          } // 有的图片服务器要求请求头需要有token
        }
      },
      watch: {
        value (val) {
          this.content = this.value
        }
      },
      // computed: {
      //   content () {
      //     return this.value
      //   }
      // },
      mounted () {
        for (let item of toolbarTips) {
          let tip = document.querySelector('.quill-editor ' + item.Choice)
          if (!tip) continue
          tip.setAttribute('title', item.title)
        }
      },
      created () {
        // this.$nextTick(() => {
        //   document.getElementById('self_typt-add-container').scrollTop = 0
        // })
      },
      methods: {
        ready() {
          Quill.register({ "formats/lineHeight": lineHeightStyle }, true)
        },
        UploadFile () {
          return '/bmms/web-bm/file'
        },
        onEditorBlur () {
          // 失去焦点事件
        },
        onEditorFocus (val) {
          // 获得焦点事件
          const quill = this.$refs.myQuillEditor.quill
          quill.format("lineHeight", 3);
          console.log('获得焦点事件----',lineHeightStyle.whitelist)
        },
        onEditorChange () {
          // 内容改变事件
          this.content = this.content.replace(/href=/g, '')
          this.$emit('input', this.content)
        },
        cuFocus () {
          this.$nextTick(function () {
            document.getElementById('self_typt-add-container').scrollTop = 0
          })
        },
        httpRequest (param) {
          const form = new FormData()
          form.append('file', param.file, param.file.name)
          Uploads(form).then(res => {
            if (res.status === 200) {
              const quill = this.$refs.myQuillEditor.quill
              // 如果上传成功
              if (res.status === 200) {
                // 获取光标所在位置
                const length = quill.getSelection().index
                // 插入图片  res.url为服务器返回的图片地址
                quill.insertEmbed(length, 'image', res.data.urlPath)
                // 调整光标到最后
                quill.setSelection(length + 1)
              } else {
                this.$message.error('图片插入失败')
              }
              // loading动画消失
              this.quillUpdateImg = false
            }
          })
        },
        // 富文本图片上传前
        beforeUpload (file) {
          // 显示loading动画
          this.quillUpdateImg = true
          const filetype = file.name.slice(
            file.name.lastIndexOf('.'),
            file.name.length
          )
          if (filetype === '.jpg' || filetype === '.png') {
            const isLt2M = file.size / 1024 / 1024 < 2
            if (!isLt2M) {
              this.$message.error('上传文件大小不能超过 2MB!')
              return false
            } else {
              return true
            }
          } else {
            this.$message.error('请上传PNG,JPG格式文件')
            return false
          }
        },
        handleChange (file, fileList) {
          var fileObj = file
          const form = new FormData()
          form.append('token', 'wnms')
          form.append('FileName', '44324')
          form.append('File', fileObj)
        }
      }
    }
    </script>
    
    <style lang="scss">
      .ql-container{
        >div:not(.ql-editor){
          >div{
            >span{
              display: none !important;
              border:1px solid red !important;
            }
          }
        }
      }
    .editor {
      line-height: normal !important;
      height: 28rem;
      overflow: hidden;
      margin-top: -1vh;
    }
    .ql-container {
      overflow: auto;
      height: calc(100% - 50px);
    }
    .ql-editor {
      p{
        img{
          max- 100%;
          margin: auto ;
          display: block ;
          float: none !important;
        }
      }
    }
    .ql-snow .ql-editor,.ql-snow .ql-editor img {
      display: block;
    }
    .ql-snow .ql-tooltip[data-mode='link']::before {
      content: '请输入链接地址:';
    }
    .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
      border-right: 0px;
      content: '保存';
      padding-right: 0px;
    }
    
    .ql-snow .ql-tooltip[data-mode='video']::before {
      content: '请输入视频地址:';
    }
    
    .ql-snow .ql-picker.ql-header .ql-picker-label::before,
    .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-toolbar {
      white-space: normal;
    }
    .ql-picker-item[data-value='10px']::before,
    .ql-picker-label[data-value='10px']::before {
      content: '10px' !important;
    }
    
    .ql-picker-item[data-value='12px']::before,
    .ql-picker-label[data-value='12px']::before {
      content: '12px' !important;
    }
    
    .ql-picker-item[data-value='14px']::before,
    .ql-picker-label[data-value='14px']::before {
      content: '14px' !important;
    }
    
    .ql-picker-item[data-value='16px']::before,
    .ql-picker-label[data-value='16px']::before {
      content: '16px' !important;
    }
    
    .ql-picker-item[data-value='18px']::before,
    .ql-picker-label[data-value='18px']::before {
      content: '18px' !important;
    }
    
    .ql-picker-item[data-value='20px']::before,
    .ql-picker-label[data-value='20px']::before {
      content: '20px' !important;
    }
    
    .ql-picker-item[data-value='24px']::before,
    .ql-picker-label[data-value='24px']::before {
      content: '24px' !important;
    }
    
    .ql-picker-item[data-value='30px']::before,
    .ql-picker-label[data-value='30px']::before {
      content: '30px' !important;
    }
    
    .ql-picker-item[data-value='32px']::before,
    .ql-picker-label[data-value='32px']::before {
      content: '32px' !important;
    }
    .ql-picker-item[data-value='38px']::before,
    .ql-picker-label[data-value='38px']::before {
      content: '38px' !important;
    }
    .ql-picker-item[data-value='48px']::before,
    .ql-picker-label[data-value='48px']::before {
      content: '48px' !important;
    }
    .ql-picker-item[data-value='64px']::before,
    .ql-picker-label[data-value='64px']::before {
      content: '64px' !important;
    }
    .ql-picker-item[data-value='72px']::before,
    .ql-picker-label[data-value='72px']::before {
      content: '72px' !important;
    }
    
    .ql-picker-item[data-value='36px']::before,
    .ql-picker-label[data-value='36px']::before {
      content: '36px' !important;
    }
    
    .ql-editor .ql-indent-1:not(.ql-direction-rtl){
      text-indent: 2em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-2:not(.ql-direction-rtl){
      text-indent: 4em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-3:not(.ql-direction-rtl){
      text-indent: 6em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-4:not(.ql-direction-rtl){
      text-indent: 8em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-5:not(.ql-direction-rtl){
      text-indent: 10em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-6:not(.ql-direction-rtl){
      text-indent: 12em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-7:not(.ql-direction-rtl){
      text-indent: 14em;
      padding-left: 0;
    }
    .ql-editor .ql-indent-8:not(.ql-direction-rtl){
      text-indent: 16em;
      padding-left: 0;
    }
    
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-label::before {
      content: "行高";
    }
    
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1"]::before {
      content: "行高1";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.5"]::before,
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.5"]::before {
      content: "行高1.5";
    }
    
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="1.75"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="1.75"]::before {
      content: "行高1.75";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="2"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="2"]::before {
      content: "行高2";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="3"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="3"]::before {
      content: "行高3";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="4"]::before,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="4"]::before {
      content: "行高4";
    }
    .ql-snow .ql-picker.ql-lineHeight .ql-picker-item[data-value="5"]::before ,.ql-snow .ql-picker.ql-lineHeight .ql-picker-label[data-value="5"]::before{
      content: "行高5";
    }
    .ql-snow .ql-picker.ql-lineHeight {
       70px;
    }
    </style>
  • 相关阅读:
    感谢那些给予我无偿帮助的人!
    软件工程总结
    《暗时间》部分感想!
    四个数混合运算,数据库存题,程序集构建三层建构
    三个数混合运算和三层架构
    需求
    数据库实现,以及工厂方法模式实现
    WPF中实现
    git简单操作
    git操作??
  • 原文地址:https://www.cnblogs.com/pangchunlei/p/15845910.html
Copyright © 2020-2023  润新知