热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Vue实现输入框回车发送和粘贴文本与图片功能

这篇文章主要为大家详细介绍了Vue如何实现聊天输入框回车发送、粘贴文本(包括HTML)、粘贴图片等功能,文中的实现方法讲解详细

上一篇中,我们初步新建了一个可“双向绑定”的聊天输入框,结合实际使用的场景,如果仅仅只是实现了“双向绑定”还不够,还必须处理粘贴文字、图片等功能。本文就在此基础上,继续探讨如何实现回车发送、粘贴文本(包括HTML)、粘贴图片等功能。话不多说,咱们开整。contenteditable的元素如何实现“双向绑定”?

实现回车发送

在一个可编辑元素中,默认回车就是换行。但是如果我们要实现回车是“发送”的功能,需要怎么处理呢?

思路:监听键盘事件,如果判断用户按下的是回车键,则执行发送逻辑,并阻止浏览器的默认行为

实现起来也可以有两种方式:

event

... handleKeydown(event) { if (event.shiftKey && event.keyCode === 13) { document.execCommand("insertLineBreak"); // 换行 } else if (event.keyCode === 13) { // 回车键 console.log("回车发送"); event.preventDefault(); return false; } }

这样就可以实现回车发送。但是这种方式是有问题的,具体如下:

  • 如果持续按下回车键,将会一直触发
  • 其他键 + 回车键也会触发此判断
  • 需要额外增加逻辑,否则输入框将不可换行

那有没有什么办法是可以解决的呢,对于Vue项目来说,可以借助按键修饰符

按键修饰符

... }, submit() { console.log("回车发送"); }, handleKeydown(event) { event.preventDefault(); return false; },

按键修饰符的具体文档可参考官网:事件处理 — Vue.js (vuejs.org),本处只重点说明.extra修饰符。.extra可以精确控制按键组合,结合keyupkeydown,上述代码翻译过来就是:只有一个回车键时,并且回弹起来才会触发“回车发送”;如果只有一个回车键,并且按下,则阻止浏览器默认事件。这样就可以实现“回车发送”。也许有人会问,换行怎么办。答案就是使用shift + enter,这也是默认的换行。如果不喜欢shift+enter就需要自己处理换行了。

优点

  • 使用方式简单
  • 可使用默认的方式换行

粘贴文本

粘贴文本不是直接使用ctrl + v嘛,这都不知道?话是这么说,但是如果我们相对粘贴的文本做些处理,直接使用ctrl + v就不合适了,而且后面还会用来粘贴图片。想要直接粘贴图片并显示,还没有原生输入框可做到吧。本处需要使用paste事件,也就是专门处理粘贴的。由于我们是要手动插入数据,因此需要阻止默认操作,需要借助prevent事件修饰符。

paste.prevent

... import onPaste from "@/utils/onPaste.js"; // 引入专门处理粘贴的方法 ... // 注意是异步处理 async onPaste(event) { const result = await onPaste(event); // 传入粘贴事件 console.log("处理后的数据", result); // 插入文本 document.execCommand("insertText", false, result.data); }

重点来了

新建onPaste.js,用来处理文本和图片的粘贴

// onPaste.js
// 定义粘贴函数
const OnPaste= (event) => {
  // 剪贴板没数据,则直接返回
  if (!event.clipboardData || !event.clipboardData.items) {
    return;
  }
  // 封装Promise
  return new Promise((resovle, reject) => {
    // 遍历剪贴板
    for(let i = 0, len = event.clipboardData.items.length; i /g; // 匹配粘贴文本中的html标签
        // 处理字符串类型,参数为回调函数
        item.getAsString(str => {
          resovle({
            data: str.replace(reg, "").replace(/(
)|(
)/g, "") // 去掉换行符
          })
        })
      } else {
        reject(new Error("不支持粘贴该类型"));
      }
    }
  })
}
export default onPaste; // 默认导出方法

关于剪贴板,由几个概念需要提前了解:clipboardDataDataTransferDataTransferItem,具体可参考clipboardData。运行结果如下:

注:本次复制的是

父组件修改子组件的值

粘贴图片

粘贴图片和粘贴问题有相同之处,也有所不同。最大的不同是显示图片,需要获取图片的src。在写代码前先想几个问题:

  • 图片展示需要提供src,那么如何获取src
  • 图片可大可小,如何限制图片的尺寸,避免超出输入框范围
  • 图片像素很高,是否需要压缩

有了这些问题,就需要一一解决。

  • 图片的压缩,采用canvas绘制指定尺寸的图片
  • base64就由canvas的toDataURL方法获得
  • 压缩时,维持图片的宽高比

话不多说,先看代码:

// DivEditable.vue
async onPaste(event) {
      const result = await onPaste(event);
      console.log("处理后的粘贴数据", result);
      const imgRegx = /^data:image/png|jpg|jpeg|gif|svg|bmp|tif/; // 支持的图片格式
      if (imgRegx.test(result.compressedDataUrl)) {
        // document.execCommand("insertImage", false, result.compressedDataUrl);
        const sel = window.getSelection(); // 获取当前光标位置
        if (sel && sel.rangeCount === 1 && sel.isCollapsed) {
          const range = sel.getRangeAt(0);
          const img = new Image();
          img.src = result.compressedDataUrl; // 使用压缩后的图片
          range.insertNode(img);
          range.collapse(false);
          sel.removeAllRanges();
          sel.addRange(range);
        }
      }
}
// onPaste.js
// 定义粘贴函数
const OnPaste= (event) => {
  ...
  return new Promise((resovle, reject) => {
    for(let i = 0, len = event.clipboardData.items.length; i  {
            resovle(data)
          })
        } else {
          // 其他文件直接返回
          resovle({
            data: file,
            type: "file"
          })
        }
      } else {
        reject(new Error("不支持粘贴该类型"));
      }
    }
  })
}
function handleImage(file, callback, maxWidth = 200) {
  console.log("粘贴的图片", file);
  if (!file || !//(?:png|jpg|jpeg|gif)/i.test(file.type)) {
    console.log("图片格式不支持");
    return;
  }
  const reader = new FileReader();
  reader.Onload= function () {
    const result = this.result;
    console.log("compressedDataUrl", result);
    let img = new Image();
    img.Onload= function() {
      let compressedDataUrl = compress(img, file.type, maxWidth, true);
      let url = compress(img, file.type, maxWidth, false);
      img = null;
      callback({
        data: file,
        compressedDataUrl,
        url,
        type: "image"
      })
    }
    img.src = result;
  };
  reader.readAsDataURL(file);
}
function compress(img, type, maxWidth, flag) {
  let canvas = document.createElement("canvas");
  let ctx2 = canvas.getContext("2d");
​
  let ratio = img.width / img.height;
  let width = img.width, height = img.height;
  // 根据flag判断是否压缩图片
  if (flag) {
    // 压缩后的图片展示在输入框
    width  = maxWidth;
    height = maxWidth / ratio; // 维持图片宽高比
  }
  canvas.width = width;
  canvas.height = height;
​
  ctx2.fillStyle = "#fff";
  ctx2.fillRect(0, 0, canvas.width, canvas.height);
  ctx2.drawImage(img, 0, 0, width, height);
​
  let base64Data = canvas.toDataURL(type, 0.75);
​
  if (type === "image/gif") {
    let regx = /(?<=data:image).*?(?=;base64)/; // 正则表示时在用于replace时,根据浏览器的不同,有的需要为字符串
    base64Data = base64Data.replace(regx, "/gif");
  }
  canvas = null;
  ctx2 = null;
  return base64Data;
}
export default onPaste;

代码实现效果图:

插入图片可使用insertImage命令插入,也可以使用Selection来插入。效果都差不多

压缩图片,其实也就是用canvas根据尺寸比例,重新绘制一张图片,并获取图片的base64

返回数据时,需要返回压缩后和原图。

如果必须要压缩图片,则在handleImage方法中,直接使用FileReader加载图片后,将base64编码返回即可。

总结

本文实现了回车发送、粘贴文本、粘贴图片的功能

涉及事件修饰符、按键修饰符、剪贴板、canvas等知识

项目地址

以上就是Vue实现输入框回车发送和粘贴文本与图片功能的详细内容,更多关于Vue输入框粘贴文本图片的资料请关注编程笔记其它相关文章!


推荐阅读
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
author-avatar
飛373227470
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有