vue实现虚拟键盘

news2025/1/18 11:41:41

本文介绍一体机常用的虚拟键盘实现,主打一个免费文章。喜欢就点个赞支持一下吧

simple-keyboard官网:simple-keyboard - simple-keyboard - Francisco HodgeSimple-keyboard is a virtual keyboard for Javascript. You can use it as an input for devices lacking a physical keyboard, such as kiosks, gamepad-cont...icon-default.png?t=N7T8https://hodgef.com/simple-keyboard/

我的效果图

 首先感谢大佬好心人分享参照链接:vue+simple-keyboard 虚拟键盘有中文(拼音),获取焦点调出键盘半封组件_vue中使用simple-keyboardde手机键盘-CSDN博客文章浏览阅读410次,点赞9次,收藏11次。vue虚拟键盘 中文切换 自动调出_vue中使用simple-keyboardde手机键盘https://blog.csdn.net/weixin_43030842/article/details/135699327

 原创目标链接 Vue使用虚拟键盘及中英文切换功能_vue.js_脚本之家这篇文章主要给大家介绍了关于Vue使用虚拟键盘及中英文切换的相关资料,有时候在大型触屏设备(如双屏设备)中往往就没有键盘去操作,所以就需要去建立一个虚拟键盘去操作,需要的朋友可以参考下icon-default.png?t=N7T8https://www.jb51.net/javascript/2907174rg.htm

1.安装所需依赖:

npm install simple-keyboard --save 
npm install simple-keyboard-layouts --save //中文字库
2.实现键盘组件:SimpleKeyboard.vue

<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,
        },
        maxLength: { default: '' },
    },
    data: () => ({
        keyboard: null,
        displayDefault: {
            '{bksp}': 'backspace',
            '{lock}': '切换',
            '{enter}': 'Enter',
            '{tab}': 'Tab',
            '{shift}': 'Shift',
            '{change}': '中文',
            '{space}': ' ',
            '{clear}': '清空',
            '{close}': '关闭'
        }
    }),
    mounted() {
        this.keyboard = new Keyboard(this.keyboardClass, {
            onChange: this.onChange,
            onKeyPress: this.onKeyPress,
            layoutCandidates: layout.layoutCandidates,
            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 ; ' {enter}",
                    '{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 : " {enter}',
                    '{shift} Z X C V B N M < > ? {clear}',
                    '{change} {space} {close}',
                ],
            },
            // 按钮展示文字
            display: this.displayDefault,
            // 按钮样式
            buttonTheme: [
                {
                    class: 'hg-red close',
                    buttons: '{close}',
                },
                {
                    class: 'change',
                    buttons: '{change}',
                },
            ],
            // 输入限制长度
            maxLength: this.maxLength,
        })
    },
    methods: {
        onChange(input) {
            this.$emit('onChange', input) // 输入值向外传递
        },
        // 重写清空按钮
        onChangeKey() {
            this.keyboard.setInput('')
            this.$emit('empty')
        },
        // @focus 触发时赋值 封装组件调用
        onChangeFocus(value) {
            this.keyboard.setInput(value)
        },
        // 点击键盘
        onKeyPress(button, $event) {
            // 点击关闭
            if (button === '{close}') {
                // 子组件调用父组件的关闭按钮方法
                this.$parent.closekeyboard()
                return false
            }
            else if (button === '{change}') {
                // 切换中英文输入法
                if (this.keyboard.options.layoutCandidates !== null) {
                    this.$set(this.displayDefault, '{change}', '英文')
                    // 切换至英文
                    this.keyboard.setOptions({
                        layoutCandidates: null,
                        display: this.displayDefault,
                    })
                } else {
                    // 切换至中文
                    this.$set(this.displayDefault, '{change}', '中文')
                    this.keyboard.setOptions({
                        layoutCandidates: layout.layoutCandidates,
                        display: this.displayDefault,
                    })
                }
            }
            else if (button === '{clear}') {
                this.onChangeKey()
            }
            else {
                let value =
                   $event.target.offsetParent.parentElement.children[0].children[0].value
                // 输入框有默认值时,覆写
                if (value) {
                    this.keyboard.setInput(value)
                }
                this.$emit('onKeyPress', button)
            }
            if (button === '{shift}' || button === '{lock}') this.handleShift()
        },
        // 切换shift/默认布局
        handleShift() {
            let currentLayout = this.keyboard.options.layoutName
            let shiftToggle = currentLayout === 'default' ? 'shift' : 'default'
            this.keyboard.setOptions({
                layoutName: shiftToggle,
            })
        },
    },
}
</script>
<style lang="less">
//这块样式可以根据自己的需求调整
@deep: ~'>>>';
.hg-candidate-box {
    position: fixed;
    width: 100%;
    font-size: 42px;
    z-index: 9999;

    .hg-candidate-box-list {
        .hg-candidate-box-list-item {
            padding: 0 20px;
        }
    }
}
.hg-rows {
    width: 100% !important;
    .hg-row {
        height: 60px;
        padding: 10px;
        .hg-button {
            height: 60px;
            font-size: 30px;
        }
    }
}
.hg-candidate-box {
    max-width: 5rem;
    left: 10px;
}
li.hg-candidate-box-list-item {
    width: 80px;
    height: 55px;
}
.hg-theme-default {
    width: 100%;
    height: 340px;
    left: 0;
    position: fixed;
    bottom: 0px;
    background-color: rgb(215, 214, 214); //间隙背景颜色
    .hg-button {
        &.hg-red {
            background: #db3e5d !important;
            color: white;
            &.close {
                max-width: 360px;
            }
        }
        &.change {
            max-width: 360px;
        }
    }
}
.hg-button {
    background-color: rgb(19, 19, 19) !important;
    color: antiquewhite;
}
.hg-button-shift {
    width: 180px;
}
.hg-button-clear {
    width: 180px;
}
.hg-button-enter {
    width: 150px;
}
.hg-button-lock {
    width: 150px;
}
</style>./SimpleKeyboard.vue

3.对键盘组件二次封装 

<template>
    <div>
        <div v-show="showKeyboard">
            <SimpleKeyboard ref="refSimpleKeyboard" class="Keyboard" @onChange="onChangeKeyboard" @empty="empty" />
        </div>
    </div>
</template>

<script>
import SimpleKeyboard from './SimpleKeyboard'
export default {
    name: 'Keyboard',
    components: {
        SimpleKeyboard
    },
    data() {
        return {
            showKeyboard: false, // 键盘默认隐藏
            value: '',
            key: ''
        }
    },
    watch: {
        key(val) {
            this.key = val
            if (this.showKeyboard) {
                this.showKeyboard = false
                setTimeout(() => {
                    this.showKeyboard = true
                }, 100)
            }
        },
    },
    methods: {
        // inpuit获取焦点显示虚拟键盘
        onInputFocus(res) {
            this.showKeyboard = true
        },
        // 给输入框赋值
        onChangeKeyboard(input) {
            this.$emit('input', { value: input, key: this.key });
        },
        // 隐藏键盘 父组件调用
        closeInputFocus() {
            this.showKeyboard = false
        },
        // 隐藏键盘 子组件调用
        closekeyboard() {
            this.showKeyboard = false
        },
        // 清空输入框
        empty() {
            this.$emit('input', { value: '', key: this.key });
        },
        // 给虚拟键盘赋当前输入框的值
        setKeyboardInput(input) {
            this.$refs.refSimpleKeyboard.onChangeFocus(input)
        }
    }
}
</script>

<style lang="less" scoped>
// 键盘样式
.Keyboard {
    position: absolute;
}
</style>

3.引用 

<template>
    <div>
/*在需要显示虚拟键盘的地方增加获取焦点事件@focus=’onInputFocus(‘form.data’,form.data)‘参数说明:onInputFocus(‘form.data’,form.data)
参数说明:第一个参数为当前输入框的双向绑定数据名字(字符串),第二个参数为当前输入框的双向绑定数据*/
        <YsInput v-model="form.data" clearable placeholder="请输入关键字" @on-focus="onInputFocus('form.data', form.data)"
            @on-blur="outInputFocus" ref="searchInput" style="margin-right:16px;width: 410px;height: 48px;"></YsInput>
/*虚拟键盘半封装说明
需要在父组件中引入引入该组件 使用时需添加ref 以及@input="updateInputValue"回调函数。 input 为虚拟键盘回传值函数 为对象结构{value: '', key: ‘**’} value为键盘回传的值 key对应变量名字*/
        <KeysInput ref="keysInput" @input="updateInputValue"></KeysInput>
    </div>
</template>

<script>
import KeysInput from './Keyboard.vue' //引入的虚拟键盘
export default {
    name: '**',
    components: { KeysInput },
    data() {
        return {
            form: {
                data: ''
            }
        }
    },
    methods: {
        // 当前input获取焦点时,显示键盘
        onInputFocus(event, value) {
            this.$refs.keysInput.showKeyboard = true
            // 传入绑定值(字符串)
            this.$refs.keysInput.key = event
            //传入当前值
            this.$refs.keysInput.setKeyboardInput(value)
        },
        // 当前input失去焦点时,隐藏键盘
        // outInputFocus() {
        //     if (this.$refs.keysInput) {
        //         this.$refs.keysInput.closeInputFocus();
        //     }
        // },
        // 回显在input框的值
        updateInputValue(value) {
            console.log(value)
            //根据key 回写input值
            let parameter = value.key.split(".") //把变量名字进行分割以免对象层级问题出现数据回传出现问题
            if (parameter.length == 1) {
                this.[value.key] = value.value
            } else {                               //参数长度为1 说明是普通变量 直接赋值
                let par0 = parameter[0]
                let par1 = parameter[1]
                this.[par0].[par1] = value.value    //赋值如果有更多层级则按需编写
            }
        },
    }
}
</script>

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

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

相关文章

内容提供者

1.Server服务编写 UserInfoProvider.java package com.tiger.chapter07_server.provider;import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sql…

基于逻辑回归实现乳腺癌预测(机械学习与大数据)

基于逻辑回归实现乳腺癌预测 将乳腺癌数据集拆分成训练集和测试集&#xff0c;搭建一个逻辑回归模型&#xff0c;对训练集进行训练&#xff0c;然后分别对训练集和测试集进行预测。输出以下结果&#xff1a; 该模型在训练集上的准确率&#xff0c;在测试集上的准确率、召回率和…

深入探讨javascript的流程控制与分支结构,以及js的函数

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属的专栏&#xff1a;前端泛海 景天的主页&#xff1a;景天科技苑 文章目录 1.流程控制与分支结构1.if分支结构2.switch case 分支结构3.循环结…

微信小程序python+django+uniapp公交路线查询系统

原生wxml开发对Node、预编译器、webpack支持不好&#xff0c;影响开发效率和工程构建。所以都会用uniapp框架开发 前后端分离&#xff0c;后端给接口和API文档&#xff0c;注重前端,接近原生系统 APP性能需求 &#xff08;1&#xff09;用户在安卓APP页面各种操作可及时得到反馈…

【项目】图书管理系统

目录 前言&#xff1a; 项目要求&#xff1a; 知识储备&#xff1a; 代码实现&#xff1a; Main&#xff1a; Books包&#xff1a; Book&#xff1a; BookList&#xff1a; Operate包&#xff1a; Operate: addOperate: deleteOperate: exitOperate: findOperate:…

express基础

express express介绍 官网传送门基于 Node.js 平台&#xff0c;快速、开放、极简的 Web 开发框架express特点 Web 应用 Express 是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架&#xff0c;它提供一系列强大的特性&#xff0c;帮助你创建各种 Web 和移动设备应用。…

UniSA: Unified Generative Framework for Sentiment Analysis

文章目录 UniSA&#xff1a;统一的情感分析生成框架文章信息研究目的研究内容研究方法1.总体架构图2.基准数据集SAEval3.Task-Specific Prompt4.Modal Mask Training5.Pre-training Tasks5.1Mask Context Modeling5.2Sentiment Polarity Prediction5.3Coarse-grained Label Con…

Object.keys()的用法

1、语法 Object.keys(obj) 参数&#xff1a;要返回其枚举自身属性的对象 返回值&#xff1a;一个表示给定对象的所有可枚举属性的字符串数组 2、处理对象&#xff0c;返回可枚举的属性数组 let person {name:“张三”,age:25,address:“深圳”,getName:function(){}} Obj…

第七十六 天WAF攻防-权限控制代码免杀异或运算变量覆盖混淆加密传参

第76天 WAF攻防-信息收集&识别&被动探针&代理池&仿指纹&白名单 知识点&#xff1a; 0、WAF介绍&模式&识别&防护等 1、信息收集被动扫描&第三方接口 2、信息收集基于爬虫&文件目录探针 3、信息收集基于用户&代理池&白名单 章…

【QT】定时器事件应用

public&#xff1a;//定时器void timerEvent(QTimerEvent *);private:int id;#include <QTimerEvent> //QWidget 默认不追踪鼠标事件 mylabel::mylabel(QWidget *parent) : QLabel(parent) {this->setMouseTracking(true);//启动定时器//参数1&#xff1a;触发定时器的…

f5——>字符串三角

暴力破解&#xff0c;双层循环&#xff0c;注意复制到新列表用append&#xff0c;这样更不容易出错 格式还是“”.join(str)

本地部署websocket服务端并结合内网穿透实现固定公网地址连接

文章目录 1. Java 服务端demo环境2. 在pom文件引入第三包封装的netty框架maven坐标3. 创建服务端,以接口模式调用,方便外部调用4. 启动服务,出现以下信息表示启动成功,暴露端口默认99995. 创建隧道映射内网端口6. 查看状态->在线隧道,复制所创建隧道的公网地址加端口号7. 以…

leetcode 3068. 最大节点价值之和【树形dp】

原题链接&#xff1a;3068. 最大节点价值之和 题目描述&#xff1a; 给你一棵 n 个节点的 无向 树&#xff0c;节点从 0 到 n - 1 编号。树以长度为 n - 1 下标从 0 开始的二维整数数组 edges 的形式给你&#xff0c;其中 edges[i] [ui, vi] 表示树中节点 ui 和 vi 之间有一…

二维码门楼牌管理系统应用场景:助力紧急服务

文章目录 前言一、紧急服务部门的传统挑战二、二维码门楼牌管理系统的优势三、实际应用案例分析四、未来展望 前言 随着城市化的快速发展&#xff0c;传统的门牌管理系统已无法满足现代社会的需求。二维码门楼牌管理系统的出现&#xff0c;为紧急服务部门&#xff08;如警察、…

鸿道Intewell-Win_V2.1.3_kyland软件版本发布说明

一、软件发布版本信息 版本号&#xff1a;V2.1.3_kyland 版本发布类型&#xff1a;trail试用版本 二、版本特点 适配 E211-1370&#xff08;J6412,8GB&#xff0c;256GB SSD&#xff09;设备 三、运行环境推荐 Intewell developer可以运行在windows7及windows10 64位 四、支…

精品中国货出海wordpress外贸独立站建站模板

旗袍唐装wordpress外贸网站模板 旗袍、唐装、华服wordpress外贸网站模板&#xff0c;适合做衣服生意的外贸公司官网使用。 https://www.jianzhanpress.com/?p3695 劳动防护wordpress外贸独立站模板 劳动防护wordpress外贸独立站模板&#xff0c;劳动保护、劳动防护用品外贸…

个人博客系列-后端项目-用户验证(5)

介绍 创建系统管理app&#xff0c;用于管理系统的用户&#xff0c;角色&#xff0c;权限&#xff0c;登录等功能&#xff0c;项目中将使用django-rest_framework进行用户认证和权限解析。这里将完成用户认证 用户验证 rest_framework.authentication模块中的认证类&#xff…

基于Python实现银行卡识别

在本文中将介绍如何使用Python和深度学习技术来实现银行卡识别功能。银行卡识别是一个在金融、安全等领域具有重要应用的问题&#xff0c;将使用深度学习模型来实现银行卡图像的识别和分类。 目录 引言数据集准备预处理和特征提取模型选择与训练模型评估与性能优化部署与应用 引…

怎么做加密文件二维码?分享文件更安全

怎么做一个加密文件二维码&#xff1f;在日常的工作和生活中&#xff0c;通过扫描二维码来查看或者下载文件的方式&#xff0c;被越来越多的人所使用&#xff0c;一方面是二维码的成本低&#xff0c;另一方面有利于提升便捷性和用户体验。 为了保证内容的隐私性和安全性&#…

Linux学习笔记——基本操作命令

目录 一、Shell 命令基础1、Shell 简介2、Shell 命令格式3、显示系统信息命令4、Shell 使用技巧 二、Linux 文件及目录管理1、Linux操作系统的目录结构2、文件及目录显示类命令3、文件及目录操作类命令4、文件内容的显示和处理5、文件查找类命令 三、vi、vim 编辑器的使用四、文…