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

news2024/11/15 17:24:14

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

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

图片:

代码:

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

第一步:创建键盘组件

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


<template>
 <el-dialog
  v-model="isShows"
  append-to-body="true"
  width="80%"
  @close="dialogClose"
 >
  <div
   class="keyboard_pop"
   @click.self="isShows = false"
  >
   <div class="input">
    <span
     v-if="!showText"
     class="placeholder"
    >
     请输入内容</span
    >
    <p v-else>
     {{ showText }}
    </p>
   </div>

   <div class="keyboard">
    <div
     v-for="(row, index) in keyList"
     :key="index"
     class="keyRow"
    >
     <div
      v-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.keyboardtext

 const 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元素,返回null
 return 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就是这个仓库的名称name
 state: () => ({
  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;

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

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

相关文章

鸿蒙 动态共享包HSP的创建和引用

1.什么是动态共享包HSP HSP&#xff08;Harmony Shared Package&#xff09;是动态共享包&#xff0c;可以包含代码、C库、资源和配置文件&#xff0c;通过HSP可以实现代码和资源的共享。HSP不支持独立发布&#xff0c;而是跟随其宿主应用的APP包一起发布&#xff0c;与宿主应…

arinc664总线协议

AFDX总线协议简介 &#xff08;1&#xff09;AFDX的传输速率高&#xff1a;带宽100MHZ&#xff0c;远远高于其他的类型的航空总线。&#xff08;2&#xff09;AFDX网络的鲁棒性高&#xff1a;AFDX的双冗余备份网络可以在某一个网络出现故障时&#xff0c;仍能正常通讯。 其中…

【C语言】结构体详解 -《探索C语言的 “小宇宙” 》

目录 C语言结构体&#xff08;struct&#xff09;详解结构体概览表1. 结构体的基本概念1.1 结构体定义1.2 结构体变量声明 2. 结构体成员的访问2.1 使用点运算符&#xff08;.&#xff09;访问成员输出 2.2 使用箭头运算符&#xff08;->&#xff09;访问成员输出 3. 结构体…

【NPU 系列专栏 2 -- NVIDIA 的 H100 和 H200 是什么?】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 NVIDIA H100 和 H200 芯片NVIDIA H100 芯片简介NVIDIA H100 主要特点NVIDIA H100 应用场景NVIDIA H100 使用举例NVIDIA H200 芯片简介NVIDIA H200 主要特点NVIDIA H200 应用场景NVIDIA H200 使用举例Summary NVIDIA H100 和 H20…

How do I increase max_new_tokens

题意&#xff1a;怎样增加 max_new_tokens 的值 问题背景&#xff1a; Im facing this error while running my code: 运行代码时遇到如下错误&#xff1a; ValueError: Input length of input_ids is 1495, but max_length is set to 20. This can lead to unexpected…

lua 游戏架构 之 游戏 AI (五)ai_autofight_find_way

这段Lua脚本定义了一个名为 ai_autofight_find_way 的类&#xff0c;继承自 ai_base 类。 lua 游戏架构 之 游戏 AI &#xff08;一&#xff09;ai_base-CSDN博客文章浏览阅读238次。定义了一套接口和属性&#xff0c;可以基于这个基础类派生出具有特定行为的AI组件。例如&…

Vue实现简单小案例

一、创建文件夹 二、引用vue.js <script src"../js/vue.js"></script> 三、准备一个容器 <div id"app"><h1>Hello,{{name}}</h1> </div> 四、创建实例 <script>new Vue({el:"#app", //el用于指…

tcache attack

Tcache Attack tcache让堆利用更加简单&#xff1a; tcache回顾&#xff1a; 在 tcache 中新增了两个结构体&#xff0c;分别是 tcache_entry 和 tcache_perthread_struct&#xff1a; /* We overlay this structure on the user-data portion of a chunk when the chunk is …

数据库概念以及增删改

1.概念 、 2.通用语法 3.数据增删改

mac大文件清理软件哪个好 mac大文件怎么清理 苹果电脑清理软件推荐免费

mac采用固态硬盘技术&#xff0c;数据存储和系统响应速度优势明显&#xff0c;但是mac的内存弊端同样体现在其固态硬盘的技术&#xff0c;导致用户无法通过机械硬盘进行扩充内存。而我们日常使用电脑会产生大量系统垃圾、用户缓存等文件&#xff0c;平时下载的电影和大型游戏安…

通信原理-实验六:实验测验

实验六 实验测验 一&#xff1a;测验内容和要求 测试需要完成以下几个步骤&#xff1a; 配置好以下网络图&#xff1b;占总分10%&#xff08;缺少一个扣一分&#xff09;根据下面图配置好对应的IP和网关以及路由等相关配置&#xff0c;保证设备之间连通正常&#xff1b;占总…

【日常记录】【JS】对一个数组,按照某个字段的值,进行分组

文章目录 1. 前言2. lodash 的分组3. Object.groupBy()参考链接 1. 前言 在开发中&#xff0c;经常会遇到一组数据&#xff0c;要按照某个字段进行分组&#xff0c;这个时候会有很多种方法&#xff0c;可以使用 forEach、reduce、等其他方法 reduce 方法 function groupBy(arr…

JS基础知识学习笔记全

JS基础知识学习笔记全 一、引入方式 1、内部脚本 &#xff08;一般定义在body下面会改善执行速度&#xff09; <body></body><!-- 内部脚本 --><script>/* 打开页面警告框显示的内容 */alert(helloJS);</script>2、外部脚本 外部专门新建一…

Redis-主从模式

目录 前言 一.主从节点介绍 二.配置redis主从结构 二.主从复制 四.拓扑结构 五.数据同步 全量复制&#xff08;Full Sync Replication&#xff09; 局部复制&#xff08;Partial Replication&#xff09; Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 前言 …

H3CNE(vlan与子接口技术)

目录 10.1 vlan间通信技术 示例一&#xff08;多臂路由&#xff09;&#xff1a; 10.2 子接口技术 示例二&#xff08;子接口技术&#xff09;&#xff1a; 10.3 vlannif接口技术 10.3.1 三层交换机与VLANNIF技术 示例三VLANNIF配置&#xff08;将交换机当成路由器使用&…

鸿蒙仓颉语言【cryptocj 库】RC2、 RC4 、AES对称加密算法

2 提供RC2、 RC4 、AES对称加密算法 前置条件&#xff1a;NA 场景&#xff1a; 支持对称加密算法。 约束&#xff1a;RC2密钥长度一般16字节&#xff0c;加密块长度8字节&#xff1b;AES加密块长度16字节 性能&#xff1a; 支持版本几何性能持平 可靠性&#xff1a; NA …

pytest:4种方法实现 - 重复执行用例 - 展示迭代次数

简介&#xff1a;在软件测试中&#xff0c;我们经常需要重复执行测试用例&#xff0c;以确保代码的稳定性和可靠性。在本文中&#xff0c;我们将介绍四种方法来实现重复执行测试用例&#xff0c;并显示当前迭代次数和剩余执行次数。这些方法将帮助你更好地追踪测试执行过程&…

3.多租户调研1

https://gitee.com/xiaoqiangBUG/hello-ruoyi-cloud.git 1.mybatis plus 的插件 TenantLineInnerInterceptor 是 MyBatis Plus 框架中的一个拦截器&#xff0c;它用于实现多租户系统的数据隔离。在多租户应用中&#xff0c;不同的租户应该只能访问到自己的数据&#xff0c;而…

URL过滤、DNS过滤和内容过滤的总结

目录 URL过滤 URL和URI URL -- 统一资源定位符 URI --- 统一资源的标识符 URL和URI之间的区别 URL过滤的方式 HTTP协议获取URL的方式 HTTP协议做控制管理的流程 HTTPS协议做控制管理的流程 1&#xff0c;配置SSL的解密功能 2&#xff0c;直接针对加密流量进行过滤 例…

javaEE-03-cookie与session

文章目录 Cookie创建Cookie获取Cookie更新CookieCookie 生命控制Cookie 有效路径 Session 会话创建和获取sessionSession 域数据的存取Session 生命周期控制浏览器和 Session 之间关联 Cookie Cookie 是服务器通知客户端保存键值对的一种技术,客户端有了 Cookie 后&#xff0c…