zoukankan      html  css  js  c++  java
  • quill富文本编辑器自定义字体、文字大小(编辑器内含element上传组件)

    如下是我们需要得到的文字大小和字体的效果:

    自定义字体、文字大小JS部分:

    //引入Qill插件
    import Quill from "quill";
    
    // 自定义字体
    
    let fontFamily = ['宋体', '黑体', '微软雅黑', '楷体', '仿宋', 'Arial', '苹方'];
    Quill.imports['attributors/style/font'].whitelist = fontFamily;
    Quill.register(Quill.imports['attributors/style/font']);
    // 自定义文字大小
    let fontSize = ['10px', '12px', '14px', '16px', '20px', '24px', '36px']
    Quill.imports['attributors/style/size'].whitelist = fontSize;
    Quill.register(Quill.imports['attributors/style/size']);
    
    const toolbarOptions = [
      [
        "bold",
        "italic",
        "underline",
        "strike",
        "blockquote",
        "code-block",
        { header: 1 },
        { header: 2 },
        { list: "ordered" },
        { list: "bullet" },
        { indent: "-1" },
        { indent: "+1" },
        { script: "sub" }, // 下标
        { script: "super" }, // 上标
        { align: [] },
        { color: [] },
        { background: [] },
        "link",
        "image",
      ],
      [{ size: fontSize }], // 文字大小
      [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
      [{ font: fontFamily }], // 字体
    ];

    自定义字体、文字大小css部分:

    /*
      文字大小
    */
    .ql-snow .ql-picker.ql-size{
      width: 70px;  // 菜单栏占比宽度
    }
    .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';
    }
    .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';
    }
    .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';
    }
    .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';
    }
    .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';
    }
    .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';
    }
    .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before,
    .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before {
      content: '36px';
    }
    
    /*
      字体
    */
    .ql-snow .ql-picker.ql-font{
      width: 80px;  // 菜单栏占比宽度
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='宋体']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='宋体']::before {
      content: '宋体';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='黑体']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='黑体']::before {
      content: '黑体';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='微软雅黑']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='微软雅黑']::before {
      content: '微软雅黑';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='楷体']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='楷体']::before {
      content: '楷体';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='仿宋']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='仿宋']::before {
      content: '仿宋';
    }
    .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';
    }
    .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='苹方']::before,
    .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='苹方']::before {
      content: '苹方';
    }

    组件完整代码(含element上传组件功能):

    <template>
      <div>
        <!-- 图片上传组件辅助-->
        <el-upload
          id="upload"
          class="editor-upload"
          :action="uploadUrl"
          :data="uploadData"
          name="file"
          :headers="headers"
          :show-file-list="false"
          :on-success="uploadSuccess"
          :on-error="uploadError"
          :before-upload="beforeUpload"
        >
        </el-upload>
    
        <!-- 富文本编辑器 -->
        <quill-editor
          class="editor"
          v-model="content"
          ref="myQuillEditor"
          :options="editorOption"
          @blur="onEditorBlur($event)"
          @focus="onEditorFocus($event)"
          @change="onEditorChange($event)"
          @ready="ready($event)"
        >
        </quill-editor>
      </div>
    </template>
    
    <script>
      //引入Qill插件
      import Quill from "quill";
    
      // 自定义字体
      let fontFamily = ['宋体', '黑体', '微软雅黑', '楷体', '仿宋', 'Arial', '苹方'];
      Quill.imports['attributors/style/font'].whitelist = fontFamily;
      Quill.register(Quill.imports['attributors/style/font']);
    
      // 自定义文字大小
      let fontSize = ['10px', '12px', '14px', '16px', '20px', '24px', '36px']
      Quill.imports['attributors/style/size'].whitelist = fontSize;
      Quill.register(Quill.imports['attributors/style/size']);
    
      // 新增行高
      let Parchment = Quill.import("parchment");
      let lingHeight = ['initial', '1', '1.5', '1.75', '2', '3', '4'];
      class lineHeightAttributor extends Parchment.Attributor.Style {}
      const lineHeightStyle = new lineHeightAttributor("lineHeight", "line-height", {
        scope: Parchment.Scope.INLINE,
        whitelist: lingHeight
      });
      Quill.register({ "formats/lineHeight": lineHeightStyle }, true);
    
      // 对齐方式样式都改成style方式,而不是class
      let Align = Quill.import('attributors/style/align');
      Align.whitelist = ['right', 'center', 'justify'];
      Quill.register(Align, true);
    
      const toolbarOptions = [
        [
          "bold",
          "italic",
          "underline",
          "strike",
          "blockquote",
          "code-block",
          { header: 1 },
          { header: 2 },
          { list: "ordered" },
          { list: "bullet" },
          { indent: "-1" },
          { indent: "+1" },
          { script: "sub" }, // 下标
          { script: "super" }, // 上标
          { align: [] },
          { color: [] },
          { background: [] },
          "link",
          "image",
        ],
        [{ size: fontSize }], // 文字大小
        [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
        [{ font: fontFamily }], // 字体
        [{ lineheight: lingHeight }]   // 行高
      ];
      export default {
        name: "Editor",
        data() {
          return {
            content: null,
            uploadUrl: 'http://',  // 上传图片接口地址
            headers: { Authorization: "Bearer " + "TOKEN" },
            editorOption: {
              modules: {
                toolbar: {
                  container: toolbarOptions,
                  handlers: {
                    // 编辑器菜单点击图片上传事件
                    image: function (value) {
                      console.log(value)
                      if (value) {
                        // 调用element上传组件
                        document.querySelector("#upload input").click();
                      }
                    },
                    lineheight: function (value) {
                      if (value) {
                        this.quill.format('lineHeight', value);
                      } else {
                        console.log(value);
                      }
                    }
                  },
                },
              },
            },
          };
        },
        computed: {
          // 图片上传额外的参数
          uploadData() {
            return { type: 1, id: '2' };
          },
        },
        methods: {
          // 失去焦点事件
          onEditorBlur() {
            this.$emit("on-blur", this.content);
          },
          onEditorFocus() {
            //获得焦点事件
          },
          // 内容改变事件
          onEditorChange() {      
            this.$emit("on-blur", this.content);
          },
          ready() {
            Quill.register({ 'formats/lineHeight': lineHeightStyle }, true);
          },
          // 上传图片前
          beforeUpload(file) {
            const isLt2M = file.size / 1024 / 1024 < 2;
            if (!isLt2M) {
              this.$message.error("上传图片不能大于 2M");
            }
          },
          // 上传图片成功
          uploadSuccess(res) {
            if (res.code == 200) {
              let img = `<img src="https:${res.data.url}" />`;
              this.content = (this.content || "") + img;
            }
          },
          // 上传图片失败
          uploadError(res) {
            console.log(res);
          },
          // 更新文本编辑器内容
          upDateContent(v) {
            this.content = v;
          },
        },
      };
    </script>
    
    <style lang="scss" scoped>
      /deep/ .quill-editor{
        width: 1000px;
        .ql-container {
          height: 300px;
        }
        .editor-upload {
          display: none;
        }
        /*
          文字大小
        */
        .ql-snow .ql-picker.ql-size{
          width: 70px;  // 菜单栏占比宽度
        }
        .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';
        }
        .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';
        }
        .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';
        }
        .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';
        }
        .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';
        }
        .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';
        }
        .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before,
        .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before {
          content: '36px';
        }
    
        /*
          字体
        */
        .ql-snow .ql-picker.ql-font{
          width: 80px;  // 菜单栏占比宽度
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='宋体']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='宋体']::before {
          content: '宋体';
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='黑体']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='黑体']::before {
          content: '黑体';
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='微软雅黑']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='微软雅黑']::before {
          content: '微软雅黑';
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='楷体']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='楷体']::before {
          content: '楷体';
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='仿宋']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='仿宋']::before {
          content: '仿宋';
        }
        .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';
        }
        .ql-snow .ql-picker.ql-font .ql-picker-label[data-value='苹方']::before,
        .ql-snow .ql-picker.ql-font .ql-picker-item[data-value='苹方']::before {
          content: '苹方';
        }
    
        /*
          标题  
        */
        .ql-snow .ql-picker.ql-header{
          width: 80px;  // 菜单栏占比宽度
        }
        .ql-snow .ql-picker.ql-header .ql-picker-label::before,
        .ql-snow .ql-picker.ql-header .ql-picker-item::before {
          content: "文本" !important;
        }
        .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" !important;
        }
        .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" !important;
        }
        .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" !important;
        }
        .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" !important;
        }
        .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" !important;
        }
        .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" !important;
        }
        //配置编辑器行高
        .ql-snow .ql-picker.ql-lineheight {
          width: 70px;  // 菜单栏占比宽度
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-label::before {
          content: '行高';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='initial']::before {
          content: '默认';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1']::before {
          content: '1';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.5']::before {
          content: '1.5';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.75']::before {
          content: '1.75';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='2']::before {
          content: '2';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='3']::before {
          content: '3';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='4']::before {
          content: '4';
        }
        .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='5']::before {
          content: '5';
        }
      }
    </style>

    开源项目地址:https://gitee.com/chenswei/vue-customize-quill

  • 相关阅读:
    进程线程协程
    面向对象完善总结
    面向对象编程
    常用模块2
    python常用模块
    随机验证码模块(random)
    带有key参数的函数filter,map,max,min
    python内置函数、匿名函数、递归
    python迭代器与生成器
    如何添加title左侧的图标
  • 原文地址:https://www.cnblogs.com/chensv/p/15603922.html
Copyright © 2011-2022 走看看