vue实现虚拟键盘

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

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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[JavaWeb学习日记]JSP+Cookie+Filter与登录+CRUD案例

目录 一.JSP 二.EL表达式与JSTL标签 三.Cookie 四.Session 五.Filter 六. 登录CRUD:品牌增删改查案例 Demo一览 1.导包 2.构建包结构 3.创建数据库表tb_brand与user 4.创建实体类 5.mybatis的配置文件和logback配置文件 6.写接口 7.工具类&#xff1a;生成图片与…

Openfeign+Ribbon+Hystrix断路器(服务降级)

热部署对于Hystrix的热不是不是很明显 所以最好修改代码之后重启服务 简介 在微服务架构中存在多个可直接调用的服务,这些服务若在调用时出现故障会导致连锁效应,也就是可能让整个系统变得不可用,这种情况我们称之为服务雪崩效应. 服务雪崩效应通常发生在微服务架构中&…

【详识JAVA语言】String 类1

String类的重要性 在C语言中已经涉及到字符串了&#xff0c;但是在C语言中要表示字符串只能使用字符数组或者字符指针&#xff0c;可以使用标准库提 供的字符串系列函数完成大部分操作&#xff0c;但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想&#xff0c;而…

SpringCloud微服务-RabbitMQ快速入门

文章目录 RabbitMQ快速入门1、什么是MQ&#xff1f;2、RabbitMQ概述3、RabbitMQ的结构和概念4、常见消息模型5、HelloWorld RabbitMQ快速入门 1、什么是MQ&#xff1f; MQ &#xff08;MessageQueue&#xff09;&#xff0c;中文是消息队列&#xff0c;字面来看就是存放消息的…

【知识整理】MySQL数据库开发设计规范

一、规范背景与目的 MySQL数据库与 Oracle、 SQL Server 等数据库相比&#xff0c;有其内核上的优势与劣势。我们在使用MySQL数据库的时候需要遵循一定规范&#xff0c;扬长避短。 本规范旨在帮助或指导RD、QA、OP等技术人员做出适合线上业务的数据库设计。在数据库变更和处理…

【LabVIEW FPGA】CIC滤波器

一、CIC滤波器应用概述 在通信数字信号上下变频时&#xff0c;经常会用到对数字信号的升采样和降采样&#xff0c;即通过CIC数字速率器实现变采样率。 二、滤波器IP 首先设置滤波器基本参数&#xff08;filter specification&#xff09; 滤波器类型&#xff08;Filter Type…

裸机编程的几种模式、架构、缺陷

目录 裸机编程模式/架构 1&#xff1a;初始化代码的编写 裸机编程模式/架构 2&#xff1a;轮询模式 裸机编程模式/架构 3&#xff1a;轮询加中断执行模式 裸机编程模式/架构 4&#xff1a;中断定时器主循环的前后台架构 裸机编程模式/架构 5&#xff1a;前后台 状态机架构…

Android开发技巧,最详细的解释小白也能听懂

今天&#xff0c;跟大家聊聊&#xff0c;Framework开发的那些事。 系统应用开发&#xff0c;现在来说&#xff0c;已经开始脱离系统&#xff0c;单独拿出来开发&#xff0c;系统定制接口&#xff0c;已提供给应用调用&#xff0c;用来增强功能。 原生的桌面&#xff0c;拨号&…

C++之获取Windows系统信息

目录 1. 操作系统版本 2. 获取CPU信息 3. 获取内存信息 4. 获取硬盘信息 5.获取网络接口信息 6.获取计算机名称、用户名 在C中&#xff0c;你可以使用Windows API函数来获取Windows系统的各种信息。以下是一些常见的API函数和示例代码&#xff0c;用于获取Windows系统信息…

深入了解 Android 中的 RelativeLayout 布局

RelativeLayout 是 Android 中常用的布局之一&#xff0c;它允许开发者基于子视图之间的相对位置来排列界面元素。在这篇博客中&#xff0c;我们将详细介绍 RelativeLayout 的各种属性&#xff0c;并提供代码示例和解释。 第一个示例 <RelativeLayoutandroid:layout_width…

腾讯云服务器99元一年是真的吗?只要61元!

腾讯云服务器99元一年是真的吗&#xff1f;假的&#xff0c;不要99&#xff0c;只要61元&#xff01;又降价了&#xff01;腾讯云服务器多少钱一年&#xff1f;61元一年起&#xff0c;2核2G3M配置&#xff0c;腾讯云2核4G5M轻量应用服务器165元一年、756元3年&#xff0c;4核16…

数据分析-Pandas数据的直方图探查

数据分析-Pandas数据的直方图探查 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

网络编程 24/3/6 作业

1、数据库的增删改 #include <myhead.h> int main(int argc, const char *argv[]) {//定义数据库句柄指针sqlite3 *kdbNULL;//打开数据库&#xff0c;不存在则创建if(sqlite3_open("./my.db",&kdb)!SQLITE_OK){printf("sqlite3_open error\n");…

如何解决无法联网的IP代理问题

目录 前言 一、检查网络连接问题 二、检查IP代理配置问题 三、更换IP代理 四、使用IP池 总结 前言 在进行网络爬虫、数据采集等涉及到频繁请求的操作中&#xff0c;IP代理是一个必不可少的工具。通过使用IP代理&#xff0c;我们可以隐藏真实的IP地址&#xff0c;防止被目…

解决DBeaver执行脚本报错No active connection

解决DBeaver执行脚本报错No active connection 1、报错问腿 2、问题解决 2.1、右键点击该数据库&#xff0c;选择SQL编辑器&#xff0c;选择新建SQL编辑器&#xff0c;然后将sql语句复制过去。 或者左击选中数据库后直接使用快捷键 Ctrl] 2.2、在Project-General中找到Scr…

Nginx入门

Nginx入门 本章目标 Ninux简介 安装 Nginx配置 负载均衡 静态化处理 本章内容 一、什么是Nginx&#xff1f; Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔赛索耶夫为俄罗斯访问量第二的http:/…

Claude3深夜震撼发布!模型特点分析,附使用教程

Claude3深夜震撼发布&#xff01;模型特点分析&#xff0c;附使用教程 引言 最新发布的Claude3引起了广泛关注&#xff0c;这次发布一举推出了三个不同类型的模型&#xff0c;分别是Claude 3 Haiku、Claude 3 Sonnet和Claude 3 Opus。每个模型都具有独特的特点和能力&#xff…

逆向案例五、爬取b站评论,表单MD5加密

1.便捷写爬虫网站&#xff1a; Convert curl commands to code 使用流程&#xff1a;又点击想要抓的包&#xff0c;复制URL&#xff08;base&#xff09;格式复制 在上面链接中粘贴即可 2.找到含有评论的包&#xff08;即main?oid)&#xff1a;观察表单发现两处参数在变化&…

protobuf 25.3在window的安装

1、下载地址 protobuf 25.3 下载完后&#xff0c;执行下面语句更新第三方库 git submodule update --init --recursive2、 cmake安装 注意&#xff1a;编译需要在vs2019及以上&#xff0c;因为abseil-cpp的编译需要是vs2019及以上

Nacos基础(注册中心和配置中心)

文章目录 参考文章一、 配置管理1、添加依赖2、添加配置信息3、创建例子4、在Nacos创建配置命名空间&#xff1a;配置集配置id配置组加载多配置文件 二、注册中心2.1、添加依赖2.2、添加项目Nacos配置2.3、添加服务发现注解这个时候你启动Nacos 如果遇到跳转链接失效请在评论区…