使用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 相关文章推荐
jQuery函数map()和each()介绍及异同点分析
Nov 08 Javascript
详解jquery事件delegate()的使用方法
Jan 25 Javascript
关于js原型的面试题讲解
Sep 25 Javascript
Bootstrap源码解读模态弹出框(11)
Dec 28 Javascript
详解React开发中使用require.ensure()按需加载ES6组件
May 12 Javascript
JavaScript判断浏览器和hack滚动条的写法
Jul 23 Javascript
layer子层给父层页面元素赋值,以达到向父层页面传值的效果实例
Sep 22 Javascript
微信小程序http连接访问解决方案的示例
Nov 05 Javascript
Bootstrap Paginator+PageHelper实现分页效果
Dec 29 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
Sep 20 Javascript
vant中的toast轻提示实现代码
Nov 04 Javascript
JavaScript实现10秒后再次获取验证码
Dec 02 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
让PHP支持页面回退的两种方法[转]
2007/02/14 PHP
php中unlink()、mkdir()、rmdir()等方法的使用介绍
2012/12/21 PHP
FireFox浏览器使用Javascript上传大文件
2013/10/30 PHP
php实现cc攻击防御和防止快速刷新页面示例
2014/02/13 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
Jquery ajaxsubmit上传图片实现代码
2010/11/04 Javascript
Js切换功能的简单方法
2010/11/23 Javascript
js 操作select和option常用代码整理
2012/12/13 Javascript
JavaScript 和 Java 的区别浅析
2013/07/31 Javascript
JS实现跟随鼠标闪烁转动色块的方法
2015/02/26 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
2016/04/13 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
ReactNative-JS 调用原生方法实例代码
2016/10/08 Javascript
浅析JavaScript中break、continue和return的区别
2016/11/30 Javascript
Vue方法与事件处理器详解
2016/12/01 Javascript
DropDownList实现可输入可选择(两种版本可选)
2016/12/07 Javascript
JS产生随机数的用法小结
2016/12/10 Javascript
js遍历获取表格内数据的方法(必看)
2017/04/06 Javascript
在ABP框架中使用BootstrapTable组件的方法
2017/07/31 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
vue中node_modules中第三方模块的修改使用详解
2019/05/31 Javascript
JavaScript修改注册表实例代码
2020/01/05 Javascript
Vue全局使用less样式,组件使用全局样式文件中定义的变量操作
2020/10/21 Javascript
跟老齐学Python之有容乃大的list(3)
2014/09/15 Python
Python cookbook(数据结构与算法)实现优先级队列的方法示例
2018/02/18 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
2018/05/28 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
Python中turtle库的使用实例
2019/09/09 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
css3的focus-within选择器的使用
2020/05/11 HTML / CSS
Html5 canvas实现粒子时钟的示例代码
2018/09/06 HTML / CSS
BSTN意大利:德国街头和运动文化高品质商店
2020/12/22 全球购物
就职演讲稿范文
2014/05/19 职场文书
维修工先进事迹
2014/05/29 职场文书
教师专业技术工作总结2015
2015/05/13 职场文书