VUE- quill-editor 编辑器使用及自定义toobar详解

news2024/11/21 2:23:21

vue使用编辑器,这里讲解编辑器quil-editor

官网:https://quilljs.com/docs/modules/toolbar 

1:安装quill-eidtor

npm i quill@1.3.6 --save

2:创建一个页面,再template里写入

<template>
  <div class="quill-editor-box" :class="{ 'h-min-40': height === 40 }">
    <div ref="myQuillEditor" :style="style" class="quill-editor">
      <!--这个是输入的各种按钮,现在是简单实用,自定义的看后面-->
      <slot name="toolbar"></slot>
      <!--这个是编辑器-->
      <div ref="editor"></div> 
    </div>
  </div>
</template>

在script中引入依赖 及quill的toobar的各种按钮的简单配置

<script>
// 主库
import _Quill from "quill";
// 核心库,不包含主题、格式化及非必要模块
import "quill/dist/quill.core.css";
// 主题样式表
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";

import katex from "katex";
import { lineHeightStyle } from "@/js/style.js";


export default {
 
  data() {
    return {
      quill: null,  //这个是ref指定quill
      editorIndex: 0,
      editorOption: {
        theme: "snow",  //这是是snow模式,一共两个模式,snow模式是有toobar的,另一个模式是没有的,只有编辑框quill
        modules: {
          toolbar: [ // 这里是tootbar样式
            // 加粗 、斜体、底部横线、中间横线
            ["bold", "italic", "underline", "strike"], 
            // 引号 、 插入代码
            ["blockquote", "code-block"], 
            // 有序列表、 无序列表
            [{ list: "ordered" }, { list: "bullet" }],
            // 字体:这里可以写一些字体,也可以自定义引入
            [{ 'font': ['SimSun', 'SimHei','Microsoft-YaHei','KaiTi','FangSong','Arial'] }],
            // 大小
            [{ size: ["12px","14px",false,"18px","20px","22px","24px","26px","28px","30px","32px","34px","36px"] }],
            // 标题
            [{ header: [1, 2, 3, 4, 5, 6, false] }],
            // 字体颜色 、 背景颜色
            [{ color: [] }, { background: [] }],
            // 排列方式
            [{ align: [] }],
            // 下标、 上标
            [{ 'script': 'sub' }, { 'script': 'super' }],
            // 缩进
            [{ 'indent': '-1' }, { 'indent': '+1' }],
            // 方向
            [{ 'direction': 'rtl' }],
            // 行高 可自定义
            [{ lineHeight: lineHeightStyle.whitelist }],
            // 清除样式
            ["clean"],
            ["link", "video", "image"],
          ], 
          formula: this.formula(),
        },
        placeholder: "请输入内容...",
        readOnly: false,
      },
    };
  },
    
  mounted() {
    this.init();
  },
  methods: {
    init() {
      // 获取quill,在这里做一些自定义处理
      this.quill = new _Quill(this.$refs["myQuillEditor"], this.editorOption);
      //禁用编辑器,防止页面自动滚动到编辑器位置
      this.quill.enable(false);
      // 初始值
      this.quill.pasteHTML(this.value || "");
      this.$nextTick(function () {
        //丢掉编辑器焦点并重新启用编辑器
        this.quill.blur();
        this.quill.enable(true);
      });

      // 自定义imageHandler 对图片按钮添加的自定义方法
      this.quill.getModule("toolbar").addHandler("image", () => {
        this.showUploadImage = true;
      });
      //  自定义插入视频 对视频按钮添加的自定义方法
      this.quill.getModule("toolbar").addHandler("video", () => {
        this.dialogFormVisible = true;
      });

      // 监听记录Index
      this.quill.on("selection-change", (range, oldRange) => {
        if (oldRange === null || oldRange.index === 0) {
          this.editorIndex = this.quill.getLength();
        } else {
          this.editorIndex = oldRange.index;
        }
      });

      // 值变化
      this.quill.on(
        "text-change",
        debounce(() => {
          let html = this.$refs.myQuillEditor.children[0].innerHTML;
          if (html === "<p><br></p>") {
            html = "";
          }
          this.onEditorChange(html);
        }, 400)
      );
    },
    onEditorChange(val) {
      this.$emit("inputvalue", val);
    },
    confirm() {
      this.quill.focus();
      if (!/^<iframe.+<\/iframe>$/.test(this.form.videoIframe)) {
        this.form.videoIframe = "";
        return;
      }
      var range = this.quill.getSelection();
      if (range) {
        //  在当前光标位置插入图片
        this.quill
          .getModule("toolbar")
          .quill.clipboard.dangerouslyPasteHTML(
            range.index,
            this.form.videoIframe
          );
        //  将光标移动到图片后面
        this.quill.getModule("toolbar").quill.setSelection(range.index + 1);
      }
      this.form.videoIframe = "";
      this.dialogFormVisible = false;
    },
    uploadImage(imgUrl) {
      let index = this.editorIndex;
      let nextIndex = this.editorIndex + 1;
      let html = this.$refs.myQuillEditor.children[0].innerHTML;
      if (html === "<p><br></p>") {
        index = 0;
        nextIndex = 1;
      }
      this.quill.insertEmbed(index, "image", imgUrl);
      this.quill.getModule("toolbar").quill.setSelection(nextIndex);
      this.showUploadImage = false;
    },
  },
};


</script>

上面这是简洁版,直接可以写出一个带有多种按钮操作的编辑器。

效果如下

 3:自定义toobar中各个小标签

除了可以对原来的小button设置颜色,还可以对原来的添加文字描述,并且还可以有长期hover后的弹框提示。

在template中原来toobar的地方换成标签

<template>
    <div class="quill-editor-box" :class="{ 'h-min-40': height === 40 }">
        <div ref="myQuillEditor" :style="style" class="quill-editor">
            <!-- <slot name="toolbar"></slot> -->
            <div id="toolbar" style="background-color: white;">
                                
                <span class="ql-formats" >
    <!-- 这里clas都是上面toobar中list中的写的前面再加一个ql-这个  -->
                    <button class="ql-bold"></button>
                    <button id="so">加粗</button>
                    <button class="ql-italic"></button>
                    <button class="ql-underline"></button>
                    <button class="ql-strike"></button>
                    <!-- spsdf -->
                </span>
                <span class="ql-formats">
                    <!-- <button class="ql-header" value="1"></button>
                        <button class="ql-header" value="2"></button> -->
                    <button class="ql-blockquote"></button>
   <!-- 这里是我添加的文字,自定义,尝试过用span用div,并不能把布局弄的很好,相反会挺糟糕。 -->
                    <button id="so">引号</button>
                    <button class="ql-code-block"></button>
                </span>

                <span class="ql-formats" id="fom2">
                    <button class="ql-list" value="ordered"></button>
                    <button class="ql-list" value="bullet"></button>
   <!-- 这里是我添加的文字,自定义,尝试过用span用div,并不能把布局弄的很好,相反会挺糟糕。 -->
                    <button id="so">列表</button>
                </span>

                <span class="ql-formats">
                    <select class="ql-font">
                        <option value="SimSun"></option>
                        <option value="SimHei"></option>
                        <option value="Microsoft-YaHei"></option>
                        <option value="KaiTi"></option>
                        <option value="FangSong"></option>
                        <option value="Arial"></option>
                    </select>
   <!-- 这里是我添加的文字,自定义,尝试过用span用div,并不能把布局弄的很好,相反会挺糟糕。 -->
                    <button id="so">字体</button>

                    <select class="ql-size">
                        <option value="12px"></option>
                        <option value="14px"></option>
                        <option selected></option>
                        <option value="18px"></option>
                        <option value="20px"></option>
                        <option value="22px"></option>
                        <option value="24px"></option>
                        <option value="26px"></option>
                        <option value="28px"></option>
                        <option value="30px"></option>
                        <option value="32px"></option>
                        <option value="34px"></option>
                        <option value="36px"></option>
                    </select>
                </span>

                <span class="ql-formats">
                    <select class="ql-header">
                        <option value="1"></option>
                        <option value="2"></option>
                        <option value="3"></option>
                        <option value="4"></option>
                        <option value="5"></option>
                        <option value="6"></option>
                        <option value="7" selected></option>
                   
                    </select>
                </span>
                
                <span class="ql-formats">
                    <select class="ql-color"></select>
                    <button id="so">颜色</button>
                    <select class="ql-background"></select>
                </span>

                <span class="ql-formats">
                    <select class="ql-align"></select>
                </span>

                <span class="ql-formats">
                    <button class="ql-script" value="sub"></button>
                    <button id="so">下标</button>
                    <button class="ql-script" value="super"></button>
                </span>
                
                <span class="ql-formats">
                    <button class="ql-indent" value="-1"></button>
                    <button class="ql-indent" value="+1"></button>
                </span>

                <span class="ql-formats">
                    <button class="ql-direction" value="rtl" title="设置方向"></button>
                </span>

                <span class="ql-formats">
                    <select class="ql-lineHeight" title="行高">
                        <option value="1" selected></option>
                        <option value="1.5"></option>
                        <option value="2"></option>
                        <option value="2.5"></option>
                        <option value="3"></option>
                        <option value="3.5"></option>
                        <option value="4"></option>
                        <option value="4.5"></option>
                    </select>
                </span>

                <span class="ql-formats">
                    <button class="ql-link"></button>
                    <button class="ql-video"></button>
                    <button class="ql-image"></button>
                    <!-- <button class="ql-formula"></button> -->
                </span>
                <span class="ql-formats">
                    <button class="ql-clean"></button>
                </span>

                <span class="ql-formats">

         <!-- title是长期hover后弹出的弹框提示 -->
           <button id="custom-img" title="设置背景" @click="setImg"></button>
                </span>
            </div>


            <div class="editor" ref="editor" style="height: 380px; background-color: white;  "></div>
        </div>
    </div>
</template>

而script中需要改成这样

export default {
    data() {
        return {
            quill: null,
            editorIndex: 0,
            editorOption: {
    
                theme: "snow",
                modules: {
                    // toolbar: this.toolbar(),
                    toolbar: '#toolbar',
                },
                placeholder: "请输入内容...",
                readOnly: false,
            },
        };
    },

css

<style lang="less" scoped>
.ql-formats {
    margin-top: 10px;
    margin-bottom: 20px;
    position: relative;
}

#so {
    position: absolute;
    top: 17px;
    padding: 0px;
    // left:50%-30px;
    left:2px;
    font-size: 11px;
    color:red;
}

</style>

样式如下

原三方按钮的颜色修改,添加提示文字(颜色和位置可以修改),添加自定义按钮(最后一个就是),长期hoverbutton后出现的弹框文字提示。

 总:写的时候会遇到很多问题,尤其是自定义的时候,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/755504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

@ConditionalOnMissingBean 不生效

还要一点需要注意的是 有顶级接口类型写接口类型,像下面这个也控制不住加载多个相同类型的Bean,因为父类最先加载,子类之间不能算作同一种类型Bean

Git详细安装教程

对于Git这块&#xff0c;我也算是个小白&#xff0c;最近在学习Git&#xff0c;所以趁此机会详细讲解一下Git的安装教程以及安装过程中遇到的问题&#xff0c;也欢迎大家对其补充&#xff0c;共同进步&#xff01; 1、下载Git Git的下载地址&#xff08;windows系统&#xff…

【STM32CubeIDE】 stm32f103的内部Flash读写,double数值读写

单片机stm32f103c8t6&#xff0c;程序存储器64Kb&#xff1a; 对其最后一页&#xff0c;第63页进行读写操作&#xff0c;空间1Kb。 写入一个32位的数据0x12345678到Flash首地址为0x0800FC00.则在Flash中存储情况如下&#xff1a; 即&#xff0c;低位地址存储数据的低位&#xf…

Python实现简易计算器

文章目录 一、需求分析1.1 功能分析1.2 性能分析 二、技术原理三、详细设计3.1 导入tkinter库3.2 定义全局变量3.3 定义添加函数3.4 定义结果函数3.5 定义清空函数3.6 创建主窗口并指定其大小和位置3.7 创建输入框3.8 创建数字和运算符按钮3.9 创建等于号和清除按钮 四、功能实…

解决打开excel时报错 “不能使用对象链接和嵌入”

问题截图 打开excel文件或者插入对象时&#xff0c;直接弹出不能使用对象链接和嵌入报错信息。 解决方法 按 winr 组合快捷键&#xff0c;打开运行&#xff0c;输入 dcomcnfg.exe 按回车确定 此时进入到组件服务管理界面&#xff0c;依次选择 组件服务-计算机-我的电脑-DOCM…

Vue+Node(Egg框架)实现文件上传保存至本地和下载文件

文章目录 1、前端代码2、后端代码 本文Node搭建的服务器是基于egg框架搭建&#xff0c;如果使用其他服务器端框架&#xff0c;可参考部分代码&#xff0c;不保证所有框架都能实现 实现效果&#xff1a; 1、前端代码 前端部分vue利用的element-ui文件上传组件&#xff0c;相关…

C++服务器框架开发11——编译调试1/cmake学习

该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见&#xff1a;[C高级教程]从零开始开发服务器框架(sylar) 上一篇&#xff1a;C服务器框架开发10——日志系统1~9代码 C服务器框架开发11——编译调试1/cmake学习 目前进度ubuntu下的cmake学习简单样例同…

【论文笔记】SINE: SINgle Image Editing with Text-to-Image Diffusion Models

声明 不定期更新自己精度论文&#xff0c;通俗易懂&#xff0c;初级小白也可以理解 涉及范围&#xff1a;深度学习方向&#xff0c;包括 CV、NLP 论文标题&#xff1a;SINE: SINgle Image Editing with Text-to-Image Diffusion Models 论文链接&#xff1a;https://www.seman…

ESXI 安装win10详细步骤

在esix安装win10安装过程遇到了坑&#xff0c;发现必须对具体选项进行设置后才可&#xff0c;做下记录&#xff1a; 1、CPU设置 &#xff12;、硬盘 3、网络适配器 4、驱动器 5、虚拟机选项

LangChain大型语言模型(LLM)应用开发(四):QA over Documents

LangChain是一个基于大语言模型&#xff08;如ChatGPT&#xff09;用于构建端到端语言模型应用的 Python 框架。它提供了一套工具、组件和接口&#xff0c;可简化创建由大型语言模型 (LLM) 和聊天模型提供支持的应用程序的过程。LangChain 可以轻松管理与语言模型的交互&#x…

动手学深度学习——图像分类数据集(代码详解)

目录 1. 图像分类数据集1.1 读取数据集1.2 读取小批量1.3 整合所有组件1.4 小结 1. 图像分类数据集 这里采用Fashion-MNIST数据集 torchvision&#xff1a;torch类型的可视化包&#xff0c;一般计算机视觉和数据可视化需要使用from torchvision import transforms&#xff1a;…

kotlin forEach循环return/break

kotlin forEach循环return/break fun main(args: Array<String>) {var a mutableListOf("0", "1", "2", "3", "4")var b mutableListOf<String>()a.forEachIndexed { index, s ->if (index > 2) {retu…

CGY-OS 正式开源!

一个初中生自己编写的一个很LOW的“OS”&#xff0c;编写不易&#xff0c;不喜勿喷&#xff1b;耗时巨大&#xff0c;引用时请说明。 接下来&#xff0c;让我们一起学习使用cgyOS。 零、配置 下载本程序后&#xff0c;在Python3.10环境下使用pip安装pygame和keyboard的最新版本…

Java二叉树

目录 一、树形结构 1.1 概念 1.2 树的性质 1.3 树的表示形式 二、二叉树 2.1 概念 2.2 两种特殊的二叉树 2.3 二叉树的性质 2.4 二叉树的存储 2.5 二叉树的基本操作 2.5.1 二叉树的遍历 2.5.2 二叉树的基本操作 一、树形结构 1.1 概念 树是一种非线性的数据结构&#xff0…

H3C-Cloud Lab-实验-DHCP中继实验

实验需求&#xff1a; 1、按照图示配置IP地址 2、配置R1为DHCP服务器&#xff0c;能够跨网段为192.168.2.0/24网段自动分配IP地址。要求分配DNS地址为202.103.24.68和202.103.0.117 3、PC3获取IP地址后&#xff0c;能够访问到192.168.1.1 实验拓扑图&#xff1a; 连接CRT 设…

Linux5.97 Ceph集群

文章目录 计算机系统5G云计算第四章 LINUX Ceph集群一、Ceph1.存储基础1&#xff09;单机存储设备2&#xff09;单机存储的问题3&#xff09;商业存储解决方案4&#xff09;分布式存储&#xff08;软件定义的存储 SDS&#xff09;5&#xff09;分布式存储的类型 2.Ceph 简介3.C…

tmux安装及使用

tmux安装及使用 tmux是一款很好使用的终端工具&#xff0c;配合shell脚本使用非常方便。 一、tmux安装 终端输入命令&#xff1a; sudo apt-get install tmux二、tmux使用 首先需要对tmux使用的名词有一个基本了解&#xff1a; session &#xff1a;会话 window : 窗口 pa…

职责链(Chain of responsibility)模式

目录 处理过程应用场景参与者协作效果实现相关模式应用与思考类图 职责链(Chain of responsibility)是一种对象行为模式&#xff0c;可以使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递…

快速配置 Rust 开发环境并编写一个小应用

安装: curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh 更新: Rust 的升级非常频繁. 如果安装 Rustup 后已有一段时间,那么很可能 Rust 版本已经过时, 运行 rustup update 获取最新版本的 Rust rustc&#xff1a;编译Rust程序 rustc只适合简单的Rust程序&#xf…

5G全网通工业三防平板Windows移动电脑

当今科技领域的快速发展为我们的生活带来了许多便利和高效性能。在这个数字化时代&#xff0c;移动设备已成为我们生活的重要组成部分。在这一领域&#xff0c;搭载全新第12代英特尔酷睿Mi5-1235U/i7-1255U处理器的工业三防平板Windows移动电脑无疑是一款引人注目的产品。 这款…