zoukankan      html  css  js  c++  java
  • 使用vue实现简单键盘,支持移动端和pc端

    常看到各种app应用中使用自定义的键盘,本例子中使用vue2实现个简单的键盘,支持在移动端和PC端使用,欢迎点赞,h5 ios输入框与键盘 兼容性优化

    实现效果:

    Keyboard.vue

    
    <template>
      <div class="keyboard" v-show="showKeyboard" v-clickoutside="closeModal">
        <p v-for="keys in keyList">
          <template v-for="key in keys">
            <i v-if="key === 'top'" @click.stop="clickKey" @touchend.stop="clickKey" class="iconfont icon-zhiding tab-top"></i>
            <i v-else-if="key === '123'" @click.stop="clickKey" @touchend.stop="clickKey" class="tab-num">123</i>
            <i v-else-if="key === 'del'" @click.stop="clickKey" @touchend.stop="clickKey" class="iconfont icon-delete key-delete"></i>
            <i v-else-if="key === 'blank'" @click.stop="clickKey" @touchend.stop="clickKey" class="iconfont icon-konggejian-jianpanyong tab-blank"></i>
            <i v-else-if="key === 'symbol'" @click.stop="clickKey" @touchend.stop="clickKey" class="tab-symbol">符</i>
            <i v-else-if="key === 'point'" @click.stop="clickKey" @touchend.stop="clickKey" class="tab-point">·</i>
            <i v-else-if="key === 'enter'" @click.stop="clickKey" @touchend.stop="clickKey" class="iconfont icon-huiche tab-enter"></i>
            <i v-else @click.stop="clickKey" @touchend.stop="clickKey">{{key}}</i>
          </template>
        </p>
      </div>
    </template>
    
    <script>
    import clickoutside from '../directives/clickoutside'
    
    export default {
      directives: { clickoutside },
      data() {
        return {
          keyList: [],
          status: 0,//0 小写 1 大写 2 数字 3 符号
          lowercase: [
            ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
            ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'],
            ['top', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'del'],
            ['123', 'point', 'blank', 'symbol', 'enter']
          ],
          uppercase: [
            ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
            ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
            ['top', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', 'del'],
            ['123', 'point', 'blank', 'symbol', 'enter']
          ],
          equip:!!navigator.userAgent.toLocaleLowerCase().match(/ipad|mobile/i)//是否是移动设备
        }
      },
      props: {
        option: {
          type: Object
        }
      },
      computed: {
        showKeyboard(){
          return this.option.show
        }
      },
    
      mounted() {
        this.keyList = this.lowercase
      },
    
      methods: {
        tabHandle({ value = '' }) {
          if(value.indexOf('tab-num') > -1){
             this.status = 2
             //数字键盘数据
          }else if(value.indexOf('key-delete') > -1){
            this.emitValue('delete')
          }else if(value.indexOf('tab-blank') > -1){
            this.emitValue(' ')
          }else if(value.indexOf('tab-enter') > -1){
            this.emitValue('
    ')
          }else if(value.indexOf('tab-point') > -1){
            this.emitValue('.')
          }else if(value.indexOf('tab-symbol') > -1){
            this.status = 3
          }else if(value.indexOf('tab-top') > -1){
            if(this.status === 0){
              this.status = 1
              this.keyList = this.uppercase
            }else{
              this.status = 0
              this.keyList = this.lowercase
            }
          }else{
    
          }
        },
    
        clickKey(event) {
          if(event.type === 'click' && this.equip) return
          let value = event.srcElement.innerText
          value && value !== '符' && value !== '·' && value !== '123'? this.emitValue(value) : this.tabHandle(event.srcElement.classList)
        },
    
        emitValue(key) {
          this.$emit('keyVal', key)
        },
    
        closeModal(e) {
          if (e.target !== this.option.sourceDom) {
            // this.showKeyboard = false
            this.$emit('close', false)
          }
        }
      }
    }
    </script>
    <style scoped lang="less">
    .keyboard {
       100%;
      margin: 0 auto;
      font-size: 18px;
      border-radius: 2px;
      padding-top: 0.5em;
      background-color: #e5e6e8;
      user-select: none;
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      z-index: 999;
      pointer-events: auto;
      p {
         95%;
        margin: 0 auto;
        height: 45px;
        margin-bottom: 0.5em;
        display: flex;
        display: -webkit-box;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: center;
        i {
          display: block;
          margin: 0 1%;
          height: 45px;
          line-height: 45px;
          font-style: normal;
          font-size: 24px;
          border-radius: 3px;
           44px;
          background-color: #fff;
          text-align: center;
          flex-grow: 1;
          flex-shrink: 1;
          flex-basis: 0;
          -webkit-box-flex: 1;
          &:active {
            background-color: darken(#ccc, 10%);
          }
        }
        .tab-top {
           50px;
          margin: 0 1%;
          background: #cccdd0;
          color: #fff;
          font-size: 24px;
        }
        .key-delete {
           50px;
          margin: 0 1%;
          color: #827f7f;
          background: #d7d7d8;
        }
        .tab-num {
          font-size: 18px;
          background: #dedede;
          color: #5a5959;
        }
        .tab-point {
           20px;
        }
        .tab-blank {
           80px;
          font-size: 12px;
          padding: 0 15px;
          color: #5a5959;
          line-height: 60px;
        }
        .tab-symbol {
           20px;
          font-size: 18px;
        }
        .tab-enter {
          font-size: 30px;
          line-height: 54px;
        }
        &:nth-child(2) {
           88%;
        }
      }
    }
    </style>
    

    KeyInput.vue

    
    <template>
      <div>
        <input type="text" ref="keyboard" v-model="inputValue" @focus="onFocus">
        <Keyboard :option="option" @keyVal="getInputValue" @close="option.show = false"></Keyboard>
      </div>
    </template>
    <script>
    import Keyboard from '../components/Keyboard'
    export default {
      components: {
        Keyboard
      },
      data() {
        return {
          option: {
            show: false,
            sourceDom: ''
          },
          inputValue: ''
        }
      },
      props: {},
      created() {},
      methods: {
        getInputValue(val) {
          if(val === 'delete'){
            this.inputValue = this.inputValue.slice(0,this.inputValue.length -1)
          }else{
            this.inputValue += val
          }
        },
        onFocus() {
          this.$set(this.option, 'show', true)
          this.$set(this.option, 'sourceDom', this.$refs['keyboard'])
        },
        //获取光标位置
        getCursorPosition() {
          let doc = this.$refs['keyboard']
          if (doc.selectionStart) return doc.selectionStart
          return -1
        },
        //设置光标位置 暂未实现
        setCursorPosition(pos) {
          let doc = this.$refs['keyboard']
          console.log(doc.setSelectionRange)
          doc.focus()
          doc.setSelectionRange(1,3)
        }
      }
    }
    </script>
    <style lang="less" scoped>
    
    </style>
    
    

    使用demo

    
    <template>
      <div>
        <key-input class="demo-class"></key-input>
      </div>
    </template>
    <script>
    import KeyInput from '../components/KeyInput'
    export default {
      components: {
        KeyInput
      },
      data() {
        return {
        }
      },
      created() {},
      methods: {
      }
    }
    </script>
    <style lang="less">
    body{
      background: #efefef;
    }
    .demo-class{
      input{
        border:1px solid #ccc;
        outline: none;
        height: 30px;
        font-size: 16px;
        letter-spacing: 2px;
        padding: 0 5px;
      }
    }
    </style>
    
    

    完整代码:https://github.com/dawnyu/vue...

    原文地址:

  • 相关阅读:
    Typora入门使用
    什么是Structed Streaming?
    Spark的join什么情况下可以避免shuffle?
    spark Executor启动过程分析
    在IDEA中使用Git
    Git和SVN的区别
    Flink on Yarn的两种模式
    如何查看执行计划
    SQL Server 堆表与栈表的对比(大表)
    SQL Server中CURD语句的锁流程分析
  • 原文地址:https://www.cnblogs.com/lalalagq/p/9960379.html
Copyright © 2011-2022 走看看