当前位置: 首页 > news >正文

vue3在元素上绑定自定义事件弹出虚拟键盘

最近开发中遇到一个需求:

焊接机器人的屏幕上集成web前端网页, 但是没有接入键盘。这就需要web端开发一个虚拟键盘,在网上找个很多虚拟键盘没有特别适合,索性自己写个简单的

图片:

代码:

(代码可能比较垃圾冗余,也没时间优化,凑合看吧)

第一步:创建键盘组件

为了方便使用,我将键盘写成组件的方式,在app.vue中引入可以全局使用


<template><el-dialogv-model="isShows"append-to-body="true"width="80%"@close="dialogClose"><divclass="keyboard_pop"@click.self="isShows = false"><div class="input"><spanv-if="!showText"class="placeholder">请输入内容</span><p v-else>{{ showText }}</p></div><div class="keyboard"><divv-for="(row, index) in keyList":key="index"class="keyRow"><divv-for="(key, keyIndex) in row":key="keyIndex":class="{delete: key === 'Delete',capslock: key === 'Caps',space: key === 'Space',capsed: key === 'Caps' && hasCapsed,li: true,}"@click="clickKey(key)">{{ key }}</div></div></div></div></el-dialog>
</template>
<script setup name="template">import useHomeStore from "@/stores/home"; //引入仓库import { storeToRefs } from "pinia"; //引入pinia转换import { ElMessage } from "element-plus";const userInfoStore = useHomeStore();const { isShows, showText, inputType } = storeToRefs(userInfoStore); // 响应式const emits = defineEmits(["updatekey"]);const keyvalue = ref(showText); //键盘输入值  this.keyboardtextconst normalKeyList = ref([["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "="],["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"],["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "Enter"],["z", "x", "c", "v", "b", "n", "m", ",", ".", "/"],["Caps", "Space", "Delete"],]); //正常键盘列表const capsedKeyList = ref([["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "="],["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\"],["A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter"],["Z", "X", "C", "V", "B", "N", "M", ",", ".", "/"],["Caps", "Space", "Delete"],]); //大写键盘列表const keyList = ref(normalKeyList.value); //键盘列表const hasCapsed = ref(false); //是否大写const clickKey = (key) => {if (inputType.value == "number") {const flag = ["0","1","2","3","4","5","6","7","8","9",'.',"Enter","Delete",].includes(key);if (!flag) {return ElMessage({message: "请输入数字",type: "warning",});}}switch (key) {case "Enter":userInfoStore.showText = keyvalue.value;userInfoStore.clickEnter();break;case "Delete":let kbt = keyvalue.value;keyvalue.value = kbt.length ? kbt.substring(0, kbt.length - 1) : kbt;break;case "Space":keyvalue.value += " ";break;case "Caps":hasCapsed.value = !hasCapsed.value;keyList.value = hasCapsed.value ? capsedKeyList.value : normalKeyList.value;break;default:keyvalue.value += key;break;}userInfoStore.showText = keyvalue.value;const dialogClose = () => {//遮罩层关闭userInfoStore.dialogClose();};};
</script>
<style lang="scss" scoped>.input {min-height: 80px;border: 1px solid #ccc;border-radius: 5px;margin-bottom: 30px;padding: 10px;}.keyboard_pop {width: 100%;}.keyRow {display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;}.keyboard {margin: 0;padding: 0;list-style: none;user-select: none;background: #fff;width: 100%;padding: 5px 15px;overflow: auto;.li {padding: 8px 18px;text-align: center;background: #fff;border-radius: 15px;font-size: 18px;font-weight: 500;box-shadow: 0 3px 6px 0px #cac9c9;&:hover {cursor: pointer;background: #03ba82;color: #fff;}&:active {top: 1px;left: 1px;}}.delete {width: 100px;}.space {width: 300px;}.capsed {position: relative;top: 1px;left: 1px;border-color: #e5e5e5;cursor: pointer;}}
</style>

第二步:注册自定义事件

(给元素绑定自定义事件,input获取光标直接可以显示虚拟键盘,方便操作!)


const isInput = (dom) => {// 检查dom是否是input元素if (dom.tagName === "INPUT") {return dom;}// 如果不是input元素,且有子节点,则递归查找子节点if (dom.children) {for (let child of dom.children) {let input = isInput(child);if (input) {return input; // 如果找到input元素,立即返回}}}// 如果没有找到input元素,返回nullreturn null;
};import pinia from "@/stores/index";
import useHomeStore from "@/stores/home"; //引入仓库
const userInfoStore = useHomeStore(pinia);export const showKeyboard = {mounted(el, binding) {const input = isInput(el);if (!input) {return console.log("绑定错误,没有input元素");}//保存input元素userInfoStore.inputDom = input;//给input注册input事件input.addEventListener("focus", function (e) {console.log("聚焦了");console.dir(e);//保存input输入框的类型userInfoStore.inputType = e.target.type;userInfoStore.inputDom = e.target;userInfoStore.isShows = true;userInfoStore.showText = e.target.value;e.target.blur();});//   input.addEventListener("blur", function (e) {//    console.log("失去聚焦了");// //    userInfoStore.isShows = false;//   });},
};

第三步:pinia保存全局变量

(全局保存变量,各个input输入的值方便保存)


import { defineStore } from "pinia";const useHomeStore = defineStore("Home", {// defineStore('userInfo',{})  Home就是这个仓库的名称namestate: () => ({inputDom: null,isShows: false,showText: "",inputType: "",}),actions: {//点击键盘确定clickEnter() {//this.inputDom.change()console.log(this.showText);this.inputDom.value = JSON.parse(JSON.stringify(this.showText))console.dir(this.inputDom);//手动触发change事件//  什么是dispatchEvent// 向一个指定的事件目标派发一个事件,//  并以合适的顺序同步调用目标元素相关的事件处理函数。//  标准事件处理规则(包括事件捕获和可选的冒泡过程)//  同样适用于通过手动的使用dispatchEvent()方法派发的事件。this.inputDom.dispatchEvent(new Event("input"));this.inputDom.dispatchEvent(new Event("change"));this.showText = "";this.inputDom.blur();this.isShows = false;this.inputDom = null;this.inputType = "";},//遮罩层关闭dialogClose() {this.showText = "";this.isShows = false;this.inputDom.blur();this.inputDom = null;this.inputType = "";},},
});export default useHomeStore;

相关文章:

vue3在元素上绑定自定义事件弹出虚拟键盘

最近开发中遇到一个需求: 焊接机器人的屏幕上集成web前端网页, 但是没有接入键盘。这就需要web端开发一个虚拟键盘,在网上找个很多虚拟键盘没有特别适合,索性自己写个简单的 图片: 代码: (代码可能比较垃圾冗余,也没时间优化,凑合看吧) 第一步:创建键盘组件 为了方便使用…...

VMware 上安装 CentOS 7 教程 (包含网络设置)

**建议先看一些我安装VMware的教程&#xff0c;有些网络配置需要做一下 1.打开VMware&#xff0c;创建虚拟机 2.勾选自定义&#xff0c;点击下一步 3.点击下一步 4.勾选“稍后安装操作系统”&#xff0c;点击下一步 5.勾选linux&#xff0c;勾选centos7&#xff0c;点击下一步…...

算法 day4 【双指针、快慢指针、环形链表】链表下

⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题专题&#xff0c;往期可看专栏&#xff0c;关注不迷路&#xff0c; 您的支持是我的最大动力&#x1f339;~ 目录 ⚡刷题计划day4继续&#xff0c;可以点个免费的赞哦~ 下一期将会开启哈希表刷题…...

智能音箱的工作原理

智能音箱的工作原理主要涉及到硬件和软件两个层面的协同工作&#xff0c;以及多个关键技术环节的配合。以下是对智能音箱工作原理的详细解析&#xff1a; 一、硬件层面 智能音箱的硬件组成通常包括主控芯片、麦克风阵列、扬声器、Wi-Fi模块和电源等部分。 主控芯片&#xff1…...

国际金融入门:国际收支与平衡表解析

在全球化的经济体系中&#xff0c;国际金融已成为我们日常生活不可或缺的一部分。了解国际金融的基础知识&#xff0c;可以帮助我们更好地理解世界经济的动态和趋势。今天&#xff0c;我们将深入探讨国际收支及其平衡表&#xff0c;以及它们是如何影响国家经济。 国际收支&…...

Modbus转BACnet/IP网关的技术实现与应用

引言 随着智能建筑和工业自动化的快速发展&#xff0c;不同通信协议之间的数据交换也变得日益重要。Modbus和BACnet/IP是两种广泛应用于自动化领域的通信协议&#xff0c;Modbus以其简单性和灵活性被广泛用于工业自动化&#xff0c;而BACnet/IP则在楼宇自动化系统中占据主导地…...

数据库连接断开后,DBAPI的数据源如何自动重连

现象 在使用DBAPI的过程中&#xff0c;如果网络抖动导致数据库连接不上&#xff0c;发现DBAPI的数据源不能重连&#xff0c;必须重启DBAPI才能连上数据库 解决办法 在数据源的连接池参数配置druid.breakAfterAcquireFailurefalse注意在企业版的4.1.1及以上版本才可以配置连接…...

Microsoft 365 Office BusinessPro LTSC 2024 for Mac( 微软Office办公套件)

Microsoft 365 Office BusinessPro LTSC 2024是一款专为商业用户设计的办公软件套件&#xff0c;它集成了Word、Excel、PowerPoint等核心应用&#xff0c;并特别包含了Microsoft Teams这一强大的协作工具。Teams将聊天、会议、文件共享、任务管理等功能整合到一个平台上&#x…...

svelte - 1. 基础知识

svelte中文官网 vue和svelt语法对比 掘金-svelte入门简介 文章目录 1、基本页面框架2、动态属性3、嵌套组件4、@html: 插入html标签,显示真实dom元素5、点击事件 on:click={handleClick}6、响应式声明7、父子组件通信8、if-else(1)if(2)if - else(3)if - else if - else…...

挖掘基于边缘无线协同感知的低功耗物联网 (LPIOT) 的巨大潜力

关键词&#xff1a;边缘无线协同感知、低功耗物联网(LPIOT)、无线混合组网、用电监测、用电计量、多角色、计量插座、无线场景感知、多角色运用、后台边缘层&#xff0c;网络边缘层&#xff0c;场景能效管理&#xff0c;场景能耗计算 在数字化和智能化日益加速的今天&#xff…...

iOS开发设计模式篇第一篇MVC设计模式

目录 1. 引言 2.概念 1.Model 1.职责 2.实现 3.和Controller通信 1.Contrller直接访问Model 2.通过委托(Delegate)模式 3.通知 4.KVO 4.设计的建议 2.View 1.职责 2.实现 3.和Controller通信 1. 目标-动作&#xff08;Target-Action&#xff09;模式 2…...

【React】全面解析:从基础知识到高级应用,掌握现代Web开发利器

文章目录 一、React 的基础知识1. 什么是 React&#xff1f;2. React 的基本概念3. 基本示例 二、React 的进阶概念1. 状态&#xff08;State&#xff09;和属性&#xff08;Props&#xff09;2. 生命周期方法&#xff08;Lifecycle Methods&#xff09;3. 钩子&#xff08;Hoo…...

神经网络之卷积神经网络

目录 一、卷积神经网络概述&#xff1a;1.卷积层&#xff1a;1.1卷积核与神经元&#xff1a;1.2卷积层作用&#xff1a;1.3多输出通道概念&#xff1a; 2.池化层&#xff1a;2.1池化层作用&#xff1a; 3.隐藏层与卷积层、池化层关系&#xff1a; 一、卷积神经网络概述&#xf…...

【Vue实战教程】之Vue工程化项目详解

Vue工程化项目 随着多年的发展&#xff0c;前端越来越模块化、组件化、工程化&#xff0c;这是前端发展的大趋势。webpack是目前用于构建前端工程化项目的主流工具之一&#xff0c;也正变得越来越重要。本章节我们来详细讲解一下如何使用webpack搭建Vue工程化项目。 1 使用we…...

DBeaver Ultimate 22.1.0 连接数据库(MySQL+Mongo+Clickhouse)

前言 继续书接上文 Docker Compose V2 安装常用数据库MySQLMongo&#xff0c;部署安装好之后我本来是找了一个web端的在线连接数据库的工具&#xff0c;但是使用过程中并不丝滑&#xff0c;最终还是选择了使用 DBeaver &#xff0c;然后发现 mongo 还需要许可&#xff0c;又折…...

探索PyMuPDF:Python中的强大PDF处理库

探索PyMuPDF&#xff1a;Python中的强大PDF处理库 背景&#xff1a;为何选择PyMuPDF 在数字化时代&#xff0c;PDF文件因其跨平台的兼容性和对格式的严格保持而成为文档交换的通用格式。然而&#xff0c;处理PDF文件往往需要专门的工具或库。这就是PyMuPDF库的用武之地。PyMuP…...

天润融通AI技术助力汽车行业销售革新,邀约到店率翻倍增长

2024年汽车行业增速放缓&#xff0c;市场竞争加剧。在这种背景下&#xff0c;人工智能的加速渗透&#xff0c;各大汽车厂商纷纷引入大模型技术&#xff0c;对传统营销方式进行升级改造&#xff0c;寻找新的增长空间。 一直以来&#xff0c;汽车厂商投入大量预算&#xff0c;对…...

ubuntu安装mysql8.0

文章目录 ubuntu版本安装修改密码取消root跳过密码验证 ubuntu版本 22.04 安装 更新软件包列表 sudo apt update安装 MySQL 8.0 服务器 sudo apt install mysql-server在安装过程中&#xff0c;系统可能会提示您设置 root 用户的密码&#xff0c;请务必牢记您设置的密码。…...

数字图像处理笔记(三) ---- 傅里叶变换的基本原理

系列文章目录 数字图像处理笔记&#xff08;一&#xff09;---- 图像数字化与显示 数字图像处理笔记&#xff08;二&#xff09;---- 像素加图像统计特征 数字图像处理笔记&#xff08;三) ---- 傅里叶变换的基本原理 文章目录 系列文章目录前言一、傅里叶变换二、离散傅里叶变…...

Golang | Leetcode Golang题解之第268题丢失的数字

题目&#xff1a; 题解&#xff1a; func missingNumber(nums []int) int {n : len(nums)total : n * (n 1) / 2arrSum : 0for _, num : range nums {arrSum num}return total - arrSum }...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...