使用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实现检测指定目录是否存在的方法
Jan 12 Javascript
JS启动应用程序的一个简单例子
May 11 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 Javascript
js判断当页面无法回退时关闭网页否则就history.go(-1)
Aug 07 Javascript
javascript中callee与caller的区别分析
Apr 20 Javascript
关于微信jssdk实现多图片上传的一点心得分享
Dec 13 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
May 25 Javascript
微信小程序页面滑动屏幕加载数据效果
Nov 16 Javascript
解析Json字符串的三种方法日常常用
May 02 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
Apr 11 Javascript
微信小程序实现简单的select下拉框
Nov 23 Javascript
一道JS算法面试题——冒泡、选择排序
Apr 21 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
Windows下安装Memcached的步骤说明
2010/04/25 PHP
php 随机记录mysql rand()造成CPU 100%的解决办法
2010/05/18 PHP
PHP文件打开、关闭、写入的判断与执行代码
2011/05/24 PHP
php从字符串创建函数的方法
2015/03/16 PHP
微信公众号OAuth2.0网页授权问题浅析
2017/01/21 PHP
TP5(thinkPHP5框架)实现显示错误信息及行号功能的方法
2019/06/03 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
传智播客学习之java 反射
2009/11/22 Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
2011/07/22 Javascript
非常好用的JsonToString 方法 简单实例
2013/07/18 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
用javascript对一个json数组深度赋值示例
2014/07/27 Javascript
浅谈JavaScript function函数种类
2014/12/29 Javascript
javascript面向对象之定义成员方法实例分析
2015/01/13 Javascript
js图片翻书效果代码分享
2015/08/20 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
JavaScript中的编码和解码函数
2017/02/15 Javascript
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
2017/05/30 Javascript
js实现多张图片延迟加载效果
2017/07/17 Javascript
基于vue.js无缝滚动效果
2018/01/25 Javascript
Rollup处理并打包JS文件项目实例代码
2018/05/31 Javascript
js 获取扫码枪输入数据的方法
2020/06/10 Javascript
Vue按时间段查询数据组件使用详解
2020/08/21 Javascript
[46:00]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第一局
2016/03/03 DOTA
python学习之面向对象【入门初级篇】
2017/01/21 Python
python直接获取API传递回来的参数方法
2018/12/17 Python
浅谈python的输入输出,注释,基本数据类型
2019/04/02 Python
详解PANDAS 数据合并与重塑(join/merge篇)
2019/07/09 Python
pandas如何处理缺失值
2019/07/31 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
2020/04/01 Python
keras训练浅层卷积网络并保存和加载模型实例
2020/07/02 Python
Python进行统计建模
2020/08/10 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
Django windows使用Apache实现部署流程解析
2020/10/12 Python
挂职自我鉴定
2014/02/26 职场文书
伏羲庙导游词
2015/02/09 职场文书