vue+simple-keyboard 虚拟键盘有中文(拼音),获取焦点调出键盘半封组件

本文讲述了作者在项目中遇到的使用前端虚拟键盘组件的问题,包括输入框切换后的兼容性问题,以及如何通过`simple-keyboard`库和自定义封装解决,以实现中英文切换和输入限制功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天临时接个需求,我们的主机产品没键盘,一直都是调主机的虚拟键盘,但是最近不知道那块出了点问题,就要用前端做一个,我之前就听说过simple-keyboard组件,就没当回事,随口就应下了,结果这个我做的这个头疼啊,什么切换input之后重新输入,切换input之后无法删除无法清空,总之就是只有一个输入框的时候就啥事没有,要是输入是一个表单,那么就是一坨,我就一点一点修修改改,改的差不多点,做出了下图效果。
哦对了我是根据大佬的直接改的目标链接 https://www.jb51.net/javascript/2907174rg.htm
在这里插入图片描述
下面是代码首先是安装依赖

npm install simple-keyboard --save 
npm install simple-keyboard-layouts --save //中文字库

1.然后就是虚拟键盘的架子先搭起来

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;
  background: rgba(256, 256, 256);
  z-index: 9999;
  .hg-candidate-box-list{
    .hg-candidate-box-list-item{
      padding: 0 20px;
    }
  }

}
.hg-rows{
  width: 100% !important;
  .hg-row {
    height: 60px;
    .hg-button{
      height: 60px;
      font-size: 30px;
    }

  }
}
.hg-theme-default {
  width: 1080px;
  height: 330px;
  left: 0;
  position: fixed;
  bottom: 10px;
  .hg-button {
    &.hg-red {
      background: #db3e5d;
      color: white;
      &.close {
        max-width: 200px;
      }
    }
    &.change {
      max-width: 200px;
    }
  }
}
</style>

这代码就直接粘贴就好了当然要看你自己的需求改一下

2.为了方便传值再给上面架子包一层

Keyboard.vue
其实就是把上面的组件引进在作为中转,让调用页面以及虚拟键盘页面的值传过来传过去更方便,而且各位自己去编写也更方便。

<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 >
      <van-row type="flex" class="search" justify="center">
         <el-input v-model="form.data" @focus="onInputFocus('form.data',form.data)" ref="searchInput"  placeholder="请输入关键词" >
         </el-input>
     </van-row>
    //ref要有 下面触发函数要用
    <KeysInput ref="keysInput" @input="updateInputValue"></KeysInput> 
  </div>
</template>

<script>
  import KeysInput from '../components/keyboard/Keyboard' //引入的虚拟键盘
  export default {
    name: '**',
    components: {KeysInput },
    data() {
      return {
        form:{
          data:''
        }
      }
    },
    methods: {
      onInputFocus(event,value) {
        // 当前input获取焦点时,显示键盘
        this.$refs.keysInput.showKeyboard = true
        // 传入绑定值(字符串)
        this.$refs.keysInput.key = event
        //传入当前值
        this.$refs.keysInput.setKeyboardInput(value)
      },
      updateInputValue(value) {
        console.log(value)
        //根据key 回写input值
        let parameter = value.key.split(".")
        if (parameter.length == 1){
          this.[value.key] = value.value
        }else {
          let par0 = parameter[0]
          let par1 = parameter[1]
          this.[par0].[par1] = value.value
        }
      },
    }
  }
</script>

具体使用方法以及函数解析

虚拟键盘半封装说明
需要在父组件中引入引入该组件 使用时需添加ref 以及@input="updateInputValue"回调函数。 input 为虚拟键盘回传值函数 为对象结构{value: '', key: ‘**’} value为键盘回传的值 key对应变量名字
updateInputValue 函数参照示例

       updateInputValue(value) {
          let parameter = value.key.split(".")   //把变量名字进行分割以免对象层级问题出现数据回传出现问题
          if (parameter.length == 1){            //参数长度为1 说明是普通变量 直接赋值
            this.[value.key] = value.value
          }else {                                //大于1 说明是对象属性 则需要进行对象属性赋值
            let par0 = parameter[0]
            let par1 = parameter[1]
            this.[par0].[par1] = value.value     //赋值如果有更多层级则按需编写
          }
        },

调起说明:
在需要显示虚拟键盘的地方增加获取焦点事件@focus=’onInputFocus(‘form.data’,form.data)‘参数说明:onInputFocus(‘form.data’,form.data)
参数说明:第一个参数为当前输入框的双向绑定数据名字(字符串),第二个参数为当前输入框的双向绑定数据
onInputFocus 函数参照示例

          onInputFocus(event,value) {
            this.$refs.keysInput.showKeyboard = true        // 当前input获取焦点时,显示键盘
            this.$refs.keysInput.key = event                // 传入绑定值(字符串)
            this.$refs.keysInput.setKeyboardInput(value)    // 传入当前值
          },
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值