使用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 相关文章推荐
IE与FireFox的兼容性问题分析
Apr 22 Javascript
通过JS 获取Mouse Position(鼠标坐标)的代码
Sep 21 Javascript
JS延迟加载加快页面打开速度示例代码
Dec 30 Javascript
jQuery实现contains方法不区分大小写的方法
Feb 13 Javascript
JS实现图片放大镜效果的方法
Feb 27 Javascript
js控制文本框只能输入中文、英文、数字与指定特殊符号的实现代码
Sep 09 Javascript
使用微信小程序开发前端【快速入门】
Dec 05 Javascript
js数字计算 误差问题的快速解决方法
Feb 28 Javascript
angularjs封装$http为factory的方法
May 18 Javascript
使用JQuery自动完成插件Auto Complete详解
Jun 18 jQuery
三步实现ionic3点击退出app程序
Sep 17 Javascript
vue中v-model对select的绑定操作
Aug 31 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
在MongoDB中模拟Auto Increment的php代码
2011/03/06 PHP
使用 PHPMAILER 发送邮件实例应用
2012/11/07 PHP
解析MySql与Java的时间类型
2013/06/22 PHP
php function用法如何递归及return和echo区别
2014/03/07 PHP
CI(CodeIgniter)框架配置
2014/06/10 PHP
destoon二次开发模板及调用语法汇总
2014/06/21 PHP
通过php修改xml文档内容的方法
2015/01/23 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
PHP实现的随机IP函数【国内IP段】
2016/07/20 PHP
IE中radio 或checkbox的checked属性初始状态下不能选中显示问题
2009/07/25 Javascript
Jquery cookie操作代码
2010/03/14 Javascript
AJAX分页的代码(后台asp.net)
2011/02/14 Javascript
JavaScript ECMA-262-3 深入解析.第三章.this
2011/09/28 Javascript
javascript插入样式实现代码
2012/02/22 Javascript
最丑的时钟效果!js canvas时钟制作方法
2016/08/15 Javascript
基于jquery实现的银行卡号每隔4位自动插入空格的实现代码
2016/11/22 Javascript
angular实现表单验证及提交功能
2017/02/01 Javascript
Node.js使用Koa搭建 基础项目
2018/01/08 Javascript
如何在vue中使用ts的示例代码
2018/02/28 Javascript
vue配置多页面的实现方法
2018/05/22 Javascript
Python第三方库的安装方法总结
2016/06/06 Python
Python3导入自定义模块的三种方法详解
2018/04/13 Python
Python将json文件写入ES数据库的方法
2019/04/10 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
python selenium实现发送带附件的邮件代码实例
2019/12/10 Python
pytorch学习教程之自定义数据集
2020/11/10 Python
css 如何让背景图片拉伸填充避免重复显示
2013/07/11 HTML / CSS
Spartoo美国:欧洲排名第一的在线时装零售商
2019/12/12 全球购物
Three Graces London官网:英国奢侈品牌
2021/03/18 全球购物
销售心得体会
2014/01/02 职场文书
演讲稿开场白
2014/01/13 职场文书
淘宝活动总结范文
2014/06/26 职场文书
师德先进个人材料
2014/12/20 职场文书
《鲁班学艺》读后感3篇
2019/11/27 职场文书
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers
ubuntu20.04虚拟机无法上网的问题及解决
2022/12/24 Servers