使用vue实现简单键盘的示例(支持移动端和pc端)


Posted in Javascript onDecember 25, 2017

常看到各种app应用中使用自定义的键盘,本例子中使用vue2实现个简单的键盘,支持在移动端和PC端使用

实现效果:

使用vue实现简单键盘的示例(支持移动端和pc端)

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('\n')
  }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 {
 width: 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 {
 width: 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;
  width: 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 {
  width: 50px;
  margin: 0 1%;
  background: #cccdd0;
  color: #fff;
  font-size: 24px;
 }
 .key-delete {
  width: 50px;
  margin: 0 1%;
  color: #827f7f;
  background: #d7d7d8;
 }
 .tab-num {
  font-size: 18px;
  background: #dedede;
  color: #5a5959;
 }
 .tab-point {
  width: 20px;
 }
 .tab-blank {
  width: 80px;
  font-size: 12px;
  padding: 0 15px;
  color: #5a5959;
  line-height: 60px;
 }
 .tab-symbol {
  width: 20px;
  font-size: 18px;
 }
 .tab-enter {
  font-size: 30px;
  line-height: 54px;
 }
 &:nth-child(2) {
  width: 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-keyborad

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
CSS和JS标签style属性对照表(方便js开发的朋友)
Nov 11 Javascript
Jquery实现的一种常用高亮效果示例代码
Jan 28 Javascript
JavaScript Math.round() 方法
Dec 18 Javascript
DeviceOne 让你一见钟情的App快速开发平台
Feb 17 Javascript
聊一聊Vue.js过渡效果
Sep 07 Javascript
Jquery针对tr td的一些实用操作方法(必看篇)
Oct 05 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
Dec 08 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
Feb 27 Javascript
JavaScript函数参数的传递方式详解
Mar 06 Javascript
详解ES6 Fetch API HTTP请求实用指南
Nov 14 Javascript
详解vue页面首次加载缓慢原因及解决方案
Nov 06 Javascript
Bootstrap实现前端登录页面带验证码功能完整示例
Mar 26 Javascript
vue的一个分页组件的示例代码
Dec 25 #Javascript
jQuery图片查看插件Magnify开发详解
Dec 25 #jQuery
AngularJS实现的生成随机数与猜数字大小功能示例
Dec 25 #Javascript
推荐10款扩展Web表单的JS插件
Dec 25 #Javascript
jQuery实现右侧抽屉式在线客服功能
Dec 25 #jQuery
用React-Native+Mobx做一个迷你水果商城APP(附源码)
Dec 25 #Javascript
jQuery简单实现向列表动态添加新元素的方法示例
Dec 25 #jQuery
You might like
CentOS安装php v8js教程
2015/02/26 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
Js操作Select大全(取值、设置选中等等)
2013/10/29 Javascript
浏览器窗口加载和大小改变事件示例
2014/02/27 Javascript
Js实现动态添加删除Table行示例
2014/04/14 Javascript
JS获取子窗口中返回的数据实现方法
2016/05/28 Javascript
使用JQuery 加载页面时调用JS的实现方法
2016/05/30 Javascript
Bootstrap中的Panel和Table全面解析
2016/06/13 Javascript
jQuery插件 Jqplot图表实例
2016/06/18 Javascript
使用JQuery选择HTML遍历函数的方法
2016/09/17 Javascript
微信小程序 UI布局常用技巧整理总结
2016/12/05 Javascript
jQuery监听浏览器窗口大小的变化实例
2017/02/07 Javascript
浅析Javascript中双等号(==)隐性转换机制
2017/10/27 Javascript
使用live-server快速搭建本地服务器+自动刷新的方法
2018/03/09 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
Vue+iview+webpack ie浏览器兼容简单处理
2019/09/20 Javascript
vue实现抽屉弹窗效果
2020/11/15 Javascript
原生js实现点击按钮复制内容到剪切板
2020/11/19 Javascript
Python基础教程之正则表达式基本语法以及re模块
2016/03/25 Python
Python网络爬虫神器PyQuery的基本使用教程
2018/02/03 Python
使用django-crontab实现定时任务的示例
2018/02/26 Python
python实现关键词提取的示例讲解
2018/04/28 Python
浅谈python图片处理Image和skimage的区别
2019/08/04 Python
pyinstaller打包程序exe踩过的坑
2019/11/19 Python
python3的UnicodeDecodeError解决方法
2019/12/20 Python
解决echarts中饼图标签重叠的问题
2020/05/16 Python
django-orm F对象的使用 按照两个字段的和,乘积排序实例
2020/05/18 Python
Python使用socket模块实现简单tcp通信
2020/08/18 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
电大本科自我鉴定
2014/02/05 职场文书
财务会计专业自荐书
2014/06/30 职场文书
2014年有孩子的离婚协议书范本
2014/10/08 职场文书
2015年员工试用期工作总结
2015/05/28 职场文书
入党群众意见范文
2015/06/02 职场文书
Java 获取Word中所有的插入和删除修订的方法
2022/04/06 Java/Android