You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js中如何为Quill编辑器设置字符限制?

Quill编辑器字符限制实现方案

Quill作为富文本编辑器,无法通过普通的@keyup/@keydown事件直接限制输入——它的内容存储和DOM结构都不同于原生输入框,必须借助Quill官方API实现字符限制,具体方案如下:

实现思路

  1. 获取Quill实例,监听编辑器的文本变化事件
  2. 计算纯文本长度(可根据需求选择是否去除空格)
  3. 当长度超出限制时,通过Quill的Delta API截断内容(保留原有格式),或直接设置纯文本(简化实现但丢失格式)

完整代码示例

Template部分

<template>
  <div>
    <quill-editor 
      ref="quillEditor"
      :options="options" 
      v-model="form.content_vn"
      @ready="onQuillReady"
    />
  </div>
</template>

Script部分

<script>
export default {
  data() {
    return {
      form: {
        content_vn: ''
      },
      options: {
        modules: {
          toolbar: [
            "bold",
            "italic",
            "underline",
            "clean",
            { align: [] }
          ],
        },
        readOnly: false,
        theme: "snow",
      },
      maxLength: 256, // 最大字符限制
      quillInstance: null
    }
  },
  methods: {
    // 编辑器初始化完成后获取实例并监听文本变化
    onQuillReady(quill) {
      this.quillInstance = quill;
      quill.on('text-change', this.handleTextChange);
    },
    handleTextChange() {
      // 获取纯文本并去除所有空格(与你之前的逻辑一致)
      const plainText = this.quillInstance.getText().replace(/\s/g, '');
      
      if (plainText.length > this.maxLength) {
        // 禁用事件监听,避免循环触发
        this.quillInstance.off('text-change', this.handleTextChange);
        
        // 基于Delta API截断内容,保留原有格式
        const delta = this.quillInstance.getContents();
        let currentCount = 0;
        let needTruncate = false;

        for (let i = 0; i < delta.ops.length; i++) {
          const op = delta.ops[i];
          if (op.insert && typeof op.insert === 'string') {
            const textNoSpace = op.insert.replace(/\s/g, '');
            if (currentCount + textNoSpace.length > this.maxLength) {
              // 计算需要保留的字符数(含空格)
              let charCount = 0;
              let truncatedStr = '';
              for (const char of op.insert) {
                if (char !== ' ') charCount++;
                truncatedStr += char;
                if (charCount === this.maxLength) break;
              }
              op.insert = truncatedStr;
              // 截断后续操作
              delta.ops = delta.ops.slice(0, i + 1);
              needTruncate = true;
              break;
            } else {
              currentCount += textNoSpace.length;
            }
          }
        }

        if (needTruncate) {
          this.quillInstance.setContents(delta);
          // 光标定位到末尾
          this.quillInstance.setSelection(this.quillInstance.getLength() - 1);
        }
        
        // 重新监听文本变化
        this.quillInstance.on('text-change', this.handleTextChange);
      }
    }
  }
}
</script>

简化版(不保留格式)

如果不需要保留富文本格式,可直接使用setText方法截断,代码更简洁:

handleTextChange() {
  const plainText = this.quillInstance.getText().replace(/\s/g, '');
  if (plainText.length > this.maxLength) {
    this.quillInstance.off('text-change', this.handleTextChange);
    let truncatedText = '';
    let count = 0;
    const fullText = this.quillInstance.getText();
    for (const char of fullText) {
      if (char !== ' ') count++;
      truncatedText += char;
      if (count === this.maxLength) break;
    }
    this.quillInstance.setText(truncatedText);
    this.quillInstance.on('text-change', this.handleTextChange);
  }
}

原方法无效原因

Quill的编辑区域并非原生input/textarea,绑定@keyup/@keydown事件时,event.target不是实际存储内容的容器,直接修改input.value也无法同步到Quill内部的内容模型,必须通过官方API操作才能生效。

内容的提问来源于stack exchange,提问作者dragonquila

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:15:40