使用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 相关文章推荐
javascript同步Import,同步调用外部js的方法
Jul 08 Javascript
javascript globalStorage类代码
Jun 04 Javascript
JavaScript 提升运行速度之循环篇 译文
Aug 15 Javascript
jquery阻止冒泡事件使用模拟事件
Sep 06 Javascript
JavaScript正则表达式之multiline属性的应用
Jun 16 Javascript
跟我学习javascript的Date对象
Nov 19 Javascript
javascript中的3种继承实现方法
Jan 27 Javascript
原JS实现banner图的常用功能
Jun 12 Javascript
ES6中Array.copyWithin()函数的用法实例详解
Sep 16 Javascript
vue生命周期实例小结
Aug 15 Javascript
微信小程序的授权实现过程解析
Aug 02 Javascript
vue+element 实现商城主题开发的示例代码
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
使用sockets:从新闻组中获取文章(二)
2006/10/09 PHP
php4的彩蛋
2006/10/09 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
thinkPHP简单实现多个子查询语句的方法
2016/12/05 PHP
php 三元运算符实例详细介绍
2016/12/15 PHP
用函数式编程技术编写优美的 JavaScript
2006/11/25 Javascript
JavaScript 密码强度判断代码
2009/09/05 Javascript
JavaScript DOM 学习第九章 选取范围的介绍
2010/02/19 Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
2013/12/12 Javascript
js分页工具实例
2015/01/28 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
分享JavaScript监听全部Ajax请求事件的方法
2016/08/28 Javascript
移动端点击态处理的三种实现方式
2017/01/12 Javascript
JS实现选定指定HTML元素对象中指定文本内容功能示例
2017/02/13 Javascript
JavaScript正则表达式简单实用实例
2017/06/23 Javascript
vue渲染时闪烁{{}}的问题及解决方法
2018/03/28 Javascript
BootStrap table实现表格行拖拽效果
2018/12/01 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
js中复选框的取值及赋值示例详解
2020/10/18 Javascript
[46:14]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第一场 12.11
2020/12/16 DOTA
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
Python更新所有已安装包的操作
2020/02/13 Python
Python图像处理库PIL的ImageEnhance模块使用介绍
2020/02/26 Python
怀俄明州飞钓:Platte River Fly Shop
2017/12/28 全球购物
Gloeilampgoedkoop荷兰:在线购买灯泡
2019/02/16 全球购物
法国在线购买汽车轮胎网站:123pneus.fr
2019/02/25 全球购物
英国鞋网:Rubber Sole
2020/03/03 全球购物
一组SQL面试题
2016/02/15 面试题
班组长工作职责
2013/12/25 职场文书
村居抓节水倡议书
2014/05/19 职场文书
2014年检验员工作总结
2014/11/19 职场文书
模范教师事迹材料
2014/12/16 职场文书
小学总务工作总结
2015/08/13 职场文书
2016创先争优活动党员公开承诺书
2016/03/24 职场文书
一条 SQL 语句执行过程
2022/03/17 MySQL