嘎嘎好用的虚拟键盘第二弹之中文输入法

news2025/1/13 13:16:46

之前还在为不用研究输入中文而暗自窃喜 这不新需求就来了(新需求不会迟到 它只是在路上飞一会儿)
找到了个博主分享的代码 是好使的 @前端-xyq 已经和原作者申请转载了 感谢~~

原作者地址:https://www.cnblogs.com/linjiangxian/p/16223681.html

抄的过程中发现 诶? 这不我之前用的那个虚拟键盘组件吗 这货还带中文呢
是的 他带 上一篇还有人问我能不能中文输入 我之前瞪两眼珠子 活拉就是没看见

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原作者的方法就是能实现的 套了两层组件keyboard-input 和 simpleKeyboard
两个utils的js方法 core.js隐藏键盘 和 mixins.js 表单字段校验(这里用element-ui el-form的prop validate校验也行)

用的过程中发现有两个报错
1.点击关闭if (button == ‘{close}’) 会报

在这里插入图片描述
if里改成如下代码即可

	if (button == '{close}') {
        let arr = document.querySelectorAll('.hg-theme-default');
        arr.forEach((ele) => {
          ele.style.visibility = 'hidden';
        });
        return false;
      }

2.中英文切换时会报错
在这里插入图片描述
改成如下代码即可

        if (this.keyboard.options.layoutCandidates !== null) {
          this.displayDefault = {
            '{bksp}': 'backspace',
            '{lock}': 'caps',
            '{tab}': 'tab',
            '{shift}': 'shift',
            '{change}': '中文',
            '{space}': ' ',
            '{clear}': '清空',
            '{close}': '关闭',
          },
          this.keyboard.setOptions({
            layoutCandidates: null,
            display: this.displayDefault,
          });
        } else {
          this.displayDefault = {
            '{bksp}': 'backspace',
            '{lock}': 'caps',
            '{tab}': 'tab',
            '{shift}': 'shift',
            '{change}': '英文',
            '{space}': ' ',
            '{clear}': '清空',
            '{close}': '关闭',
          },
          this.keyboard.setOptions({
            layoutCandidates: layout.layoutCandidates,
            display: this.displayDefault,
          });
        }

我这里修改了simpleKeyboard内的部分代码 做了点样式调整

<template>
  <div :class="keyboardClass"></div>
</template>

<script>
import Keyboard from 'simple-keyboard';
import 'simple-keyboard/build/css/index.css';
import layout from 'simple-keyboard-layouts/build/layouts/chinese'; // 中文输入法

export default {
  name: 'SimpleKeyboard',
  props: {
    keyboardClass: {
      default: 'simple-keyboard',
      type: String,
    },
    input: {
      type: String,
      default: '',
    },
  },
  data: () => ({
    keyboard: null,
  }),
  mounted() {
    this.keyboard = new Keyboard(this.keyboardClass, {
      onChange: this.onChange,
      onKeyPress: this.onKeyPress,
      ...layout
    });
    this.setKeyboard()
  },
  methods: {
    setKeyboard() {
      this.keyboard.setOptions({
      layoutName: "shift",
      layoutCandidatesPageSize: 10,
      theme: "hg-theme-default hg-layout-default myTheme",
      layout: {
        // 默认布局
        default: [
          '` 1 2 3 4 5 6 7 8 9 0 - = {bksp}',
          '{tab} q w e r t y u i o p [ ] \\',
          "{lock} a s d f g h j k l ; '",
          '{shift} z x c v b n m , . / {clear}',
          '{change} {space} {close}',
        ],
        // 切换shift布局
        shift: [
          '~ ! @ # $ % ^ & * ( ) _ + {bksp}',
          '{tab} Q W E R T Y U I O P { } |',
          '{lock} A S D F G H J K L : "',
          '{shift} Z X C V B N M < > ? {clear}',
          '{change} {space} {close}',
        ],
      },
      buttonTheme: [
        {
          class: 'hg-red close',
          buttons: '{close}',
        },
        {
          class: 'hg-red change',
          buttons: '{change}',
        },
      ],
      display: {
        '{bksp}': 'backspace',
        '{lock}': 'caps',
        '{tab}': 'tab',
        '{shift}': 'shift',
        '{change}': '英文',
        '{space}': ' ',
        '{clear}': '清空',
        '{close}': '关闭',
      }
    });
    },

    onChange(input) {
      this.$emit('onChange', input);
    },
    
    // 点击键盘
    onKeyPress(button, $event) {
      console.log("onKeyPress -> $event", $event)
      if (button == '{close}') {
        let arr = document.querySelectorAll('.hg-theme-default');
        arr.forEach((ele) => {
          ele.style.visibility = 'hidden';
        });
        return false;
      } else if (button == '{change}') { // 切换中英输入法        
        if (this.keyboard.options.layoutCandidates !== null) {
          this.displayDefault = {
            '{bksp}': 'backspace',
            '{lock}': 'caps',
            '{tab}': 'tab',
            '{shift}': 'shift',
            '{change}': '中文',
            '{space}': ' ',
            '{clear}': '清空',
            '{close}': '关闭',
          },
          this.keyboard.setOptions({
            layoutCandidates: null,
            display: this.displayDefault,
          });
        } else {
          this.displayDefault = {
            '{bksp}': 'backspace',
            '{lock}': 'caps',
            '{tab}': 'tab',
            '{shift}': 'shift',
            '{change}': '英文',
            '{space}': ' ',
            '{clear}': '清空',
            '{close}': '关闭',
          },
          this.keyboard.setOptions({
            layoutCandidates: layout.layoutCandidates,
            display: this.displayDefault,
          });
        }
      } else if (button == '{clear}') {
        this.keyboard.clearInput();
      } else {
        let value = $event.target.offsetParent.parentElement.children[0].children[0].value;
        if (value) {
          this.keyboard.setInput(value);
        }        
      }
      this.$emit('onKeyPress', button);
      /**
       * If you want to handle the shift and caps lock buttons
       */
      if (button === '{shift}' || button === '{lock}') this.handleShift();
    },


    handleShift() {
      let currentLayout = this.keyboard.options.layoutName;
      let shiftToggle = currentLayout === "default" ? "shift" : "default";

      this.keyboard.setOptions({
        layoutName: shiftToggle
      });
    } 

  },
  watch: {
    input(input) {
      this.keyboard.setInput(input);
    },
  },
};
</script>

<style scoped>
  .hg-theme-default {
    width: 80%;
    padding: 15px;
    box-shadow: 0 4px 0 #b2b2b2, 0 7px 16px rgba(0,0,0,.3);
  }
  .hg-theme-default /deep/ .hg-button {
    height: 50px;    
  }
  .hg-theme-default /deep/ .hg-red {
    background: #a8001e!important;
    color: white;
  }
  .hg-theme-default /deep/ .hg-red {
    max-width: 200px;
  }
  .hg-theme-default /deep/ .close {
    max-width: 200px;
  }
  .hg-theme-default /deep/ .change {
    max-width: 200px;
  }

  .hg-theme-default /deep/ .hg-button{
    height: 50px;
    margin: 8px 10px;
    font-size: 23px;
    background-color: #fff;
    border-radius: 8px;
    cursor: pointer;
    -webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0,0,0,.7);
    box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0,0,0,.7);
  }

  .hg-theme-default /deep/ .hg-button:active {
    box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0,0,0,.9);
    background-color: #efefef;
  }

  .hg-theme-default /deep/ .hg-layout-default .hg-button.bksp {
    height: 50px;
    margin: 8px 10px;
    font-size: 23px;
    background-color: #fff;
    border-radius: 8px;
    cursor: pointer;
    -webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0,0,0,.7);
    box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0,0,0,.7);
    background: #a8001e;
    color: white;
  }

  .hg-theme-default /deep/ .hg-layout-default .hg-button.bksp:active {
    box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0,0,0,.9);
    background-color: #efefef;
    color: #000000;
  }

  .hg-theme-default /deep/ .hg-layout-default .hg-button.enter {
    height: 50px;
    margin: 5px 8px;
    font-size: 23px;
    background-color: #fff;
    border-radius: 8px;
    cursor: pointer;
    -webkit-box-shadow: 0 4px 0 #b2b2b2, 0 5px 10px rgba(0,0,0,.7);
    box-shadow: 0 3px 0 #b2b2b2, 0 4px 6px rgba(0,0,0,.7);
    background: #a8001e;
    color: white;
  }

  .hg-theme-default /deep/ .hg-layout-default .hg-button.enter:active {
    box-shadow: 0 4px 0 #717070, 0 5px 3px rgba(0,0,0,.9);
    background-color: #efefef;
    color: #000000;
  }
</style>

外层组件keyboard-input的css样式

<style scoped>
  .input-keyboard /deep/ .hg-theme-default {
    position: fixed;
    left: 50%;
    bottom: 230px;
    transform: translate(-50%);
    visibility: hidden;
    margin-top: 20px;
    z-index: 2000; 
  }

  .input-keyboard /deep/ .hg-candidate-box {
    position: static;
    transform: translateY(0);
    border-bottom: none;
    border-radius: none;
  }

  .input-keyboard /deep/.hg-rows {
    font-size: 25px;
  }
  
  .input-keyboard /deep/ .hg-candidate-box {
    font-size: 23px;
  } 
  .input-keyboard /deep/ li.hg-candidate-box-list-item {   
    height: 60px;
    width: 40px;
    padding: 0 6px;
  }
</style>


<style scoped>
  .input-keyboard /deep/ .el-input__inner {
    color: #000;
    border-color: #adadad;
    height: 45px;
  }
  .input-keyboard /deep/ .el-form-item.is-error .el-input__inner, .el-form-item.is-error .el-input__inner:focus, .el-form-item.is-error .el-textarea__inner, .el-form-item.is-error .el-textarea__inner:focus, .el-message-box__input input.invalid, .el-message-box__input input.invalid:focus {
    border-color: #a8001c;
  }
  .input-keyboard /deep/ .el-form-item__error {
    color: #a8001c;
    font-size: 17px;
    line-height: 1;
    padding-top: 2px;
    position: absolute;
    top: 100%;
    left: 0;
  }
  .input-keyboard /deep/ .el-form-item {
    margin-bottom: 50px;
  }
  .input-keyboard /deep/ .el-form-item__label {
    font-size: 25px;
    color: #000000;
  }
  .input-keyboard /deep/ .el-input.is-disabled .el-input__inner {
    font-size: 25px;
    height: 45px;
    background-color: #fff;
    border-color: #adadad;
    color: #000;
    cursor: not-allowed;
  }
  .input-keyboard /deep/ .el-textarea__inner {   
    font-size: 25px;
    color: #000000;   
  }
  .input-keyboard /deep/ .el-textarea.is-disabled .el-textarea__inner {
    font-size: 25px;
    height: 45px;
    background-color: #fff;
    border-color: #adadad;
    color: #000;
    cursor: not-allowed;
    font-family: Avenir,Helvetica,Arial,sans-serif;
  }
  .input-keyboard /deep/ .el-input.is-active .el-input__inner, .el-input__inner:focus {
    border-color: #a8001e;
    outline: 0;
  }
  .input-keyboard /deep/ .el-input.is-disabled .el-input__wrapper {
    background-color: #ffffff;
  } 
  .input-keyboard /deep/ .el-form-item.is-error .el-select-v2__wrapper, .el-form-item.is-error .el-select-v2__wrapper:focus, .el-form-item.is-error .el-textarea__inner, .el-form-item.is-error .el-textarea__inner:focus {
    box-shadow: 0 0 0 1px #a8001e inset;
  }
</style>

再次感谢作者@前端-xyq

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

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

相关文章

初识C++ · 模板初阶

目录 1 泛型编程 2 函数模板 3 类模板 1 泛型编程 模板是泛型编程的基础&#xff0c;泛型我们碰到过多次了&#xff0c;比如malloc函数返回的就是泛型指针&#xff0c;需要我们强转。 既然是泛型编程&#xff0c;也就是说我们可以通过一个样例来解决类似的问题&#xff0c…

通过AOP实现项目中业务服务降级功能

最近项目中需要增强系统的可靠性&#xff0c;比如某远程服务宕机或者网络抖动引起服务不可用&#xff0c;需要从本地或者其它地方获取业务数据&#xff0c;保证业务的连续稳定性等等。这里简单记录下业务实现&#xff0c;主要我们项目中调用远程接口失败时&#xff0c;需要从本…

Springboot 单体thymeleaf极简门户网站

企业门户网站&#xff0c;基于Springboot和layui 1、原介绍 使用技术&#xff1a;后端框架&#xff1a;SpringBoot&#xff0c;Mybatisplus ### 数据库&#xff1a;MySQL,redis ## 前端框架&#xff1a;Layui ## 权限框架&#xff1a;shiro ## 网页模板引擎&#xff1a;thyme…

Python基础详解三

一&#xff0c;函数的多返回值 def methodReturn():return 1,2x,ymethodReturn() print(x,y) 1 2 二&#xff0c;函数的多种参数使用形式 缺省参数&#xff1a; def method7(name,age,address"淄博"):print("name:"name",age"str(age)&quo…

案例分享:BACnet转Modbus提升暖通系统互操作性

现代智能建筑中系统的集成与互操作性是决定其智能化程度的关键因素。随着技术的发展&#xff0c;不同标准下的设备共存成为常态&#xff0c;而BACnet与Modbus作为楼宇自动化领域广泛采用的通讯协议&#xff0c;它们之间的无缝对接显得尤为重要。本文将通过一个实际案例&#xf…

react状态管理之state

第三章 - 状态管理 随着你的应用不断变大&#xff0c;更有意识的去关注应用状态如何组织&#xff0c;以及数据如何在组件之间流动会对你很有帮助。冗余或重复的状态往往是缺陷的根源。在本节中&#xff0c;你将学习如何组织好状态&#xff0c;如何保持状态更新逻辑的可维护性&…

Densenet+SE

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊# 前言 前言 这周开始学习关于经典模型的改进如加注意力机制&#xff0c;这周学习Densenet加通道注意力即SE注意力机制。 ##SE注意力机制简介 SE&#xff08;…

Flutter笔记:手动配置VSCode中Dart代码自动格式化

Flutter笔记 手动配置VSCode中Dart代码自动格式化 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csd…

景源畅信电商:抖音小店需要请专业人员装修店铺吗?

在数字营销的海洋中&#xff0c;抖音小店如一艘航船&#xff0c;装修得当才能吸引顾客登船。那么&#xff0c;小店是否需要请专业人员来装修呢?答案是肯定的。 一、视觉冲击力是关键 专业设计师擅长运用色彩、布局与图像创造出强烈的视觉冲击力&#xff0c;这对于抓住用户的注…

亲测快捷高效的编写测试用例方法

前言 测试用例是任何测试周期的第一步&#xff0c;对任何项目都非常重要。如果在此步骤中出现任何问题&#xff0c;则在整个软件测试过程中都会扩大影响。如果测试人员在创建测试用例模板时使用正确的过程和准则&#xff0c;则可以避免这种情况。 在本篇文章中将分享一些简单而…

stack的使用

1.栈的定义 我们可以看到模板参数里面有一个容器适配器 &#xff0c;什么是适配器&#xff1f;比如充电器就叫做电源适配器&#xff0c;用在做转换&#xff0c;对电压进行相关的转换适配我们的设备。栈&#xff0c;队列不是自己直接管理数据&#xff0c;是让其他容器管理数据&a…

MVC与MVVM架构模式

1、MVC MVC&#xff1a;Model-View-Controller&#xff0c;即模型-视图-控制器 MVC模式是一种非常经典的软件架构模式。从设计模式的角度来看&#xff0c;MVC模式是一种复合模式&#xff0c;它将多个设计模式结合在一种解决方案中&#xff0c;从而可以解决许多设计问题。 MV…

【Linux】线程的内核级理解详谈页表以及虚拟地址到物理地址之间的转化

一、线程的概念 对于进程来说&#xff0c;进程创建时间和空间成本较高&#xff0c;因为进程是承担分配系统资源的基本实体&#xff0c;所以线程的出现就成为了必然。Linux线程与进程非常相似&#xff0c;Linux设计者在设计之初觉得如果再为线程设计数据结构和调度算法就会使整个…

JUC下的ScheduledThreadPoolExecutor详解

ScheduledThreadPoolExecutor是Java并发编程框架中一个强大且灵活的线程池实现&#xff0c;专为定时与周期性任务而设计。作为ThreadPoolExecutor的子类&#xff0c;它不仅继承了线程池管理的高效与灵活性&#xff0c;还内置了基于优先级队列的延迟任务调度机制&#xff0c;支持…

【stm-4】PWM驱动LED呼吸灯 PWM驱动舵机PWM驱动直流电机

1.PWM驱动LED呼吸灯 void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); //结构体初始化输出比较单元 void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef*…

智能家居4 -- 添加接收消息的初步处理

这一模块的思路和前面的语言控制模块很相似&#xff0c;差别只是调用TCP 去控制 废话少说&#xff0c;放码过来 增添/修改代码 receive_interface.c #include <pthread.h> #include <mqueue.h> #include <string.h> #include <errno.h> #include <…

算法学习(6)-最短路径

目录 Floyd-Warshall算法 Dijkstra算法 Bellman-Ford算法 Bellman-Ford的队列优化 最短路径算法对比分析 Floyd-Warshall算法 现在回到问题&#xff1a;如何求任意两点之间的最短路径呢&#xff1f; 通过之前的学习&#xff0c; 我们知道通过深度或广度优先搜索可以求出两…

学习记录:AUTOSAR R20-11的阅读记录(五)【CP(5.11-5.19)】完

接上回&#xff1a;学习记录&#xff1a;AUTOSAR R20-11的阅读记录&#xff08;四&#xff09;【CP&#xff08;5.6-5.10&#xff09;】 五、CP 11、General&#xff08;4个&#xff09; 5.11 File Name 说明 1 AUTOSAR_EXP_ LayeredSoftwareArchitecture.pdf 描述了AUTO…

多模态大模型MLLM VIT CLIP BLIP

一、Vit模型介绍 Vit&#xff08;Vision Transformer&#xff09;即将Transformer应用于视觉领域。 Transformer输入输出都是一个序列&#xff0c;若需要应用于视觉领域&#xff0c;则需要考虑如何将一个2d图片转化为一个1d的序列&#xff0c;最直观的想法将图片中的像素点输…

merge函数占用内存过大

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…