基于Vue实现timepicker


Posted in Javascript onApril 25, 2017

在github上看到的练习,看了遍代码后,按自己的思路再修改了一下。
先放原址:https://github.com/graysheeep/vue-material-timepicker。
自己做的在线demo:http://jsbin.com/dumace/2/edit?html,js,output

主要用到的还是Vue的基本知识而已,不过要想到的细节很多。
先放效果,点击上框,显示timepicker。而且可以根据点击的是时还是分来改变圆盘的数字。

基于Vue实现timepicker

这里我用了两个组件,<time-box>和<time-picker>,这里的时和分的数值我挂在了根实例中,因为两个组件都需要这两个值,所以想了想我决定还是挂在根实例,通过动态绑定到组件中。HTML见在线demo。

根组件

var app = new Vue({
 el: "#app",
 data: {
  minutes: 15,
  hour: 8,
  showTimePicker: false,
  current: 0  //0为时、1为分
 },
 created: function(){
  this.$on("closeTimePicker",function() {  //监听关闭time-picker
   this.showTimePicker = false;
  }),
  this.$on("openTimePicker",function() {
   this.showTimePicker = true;
  }),
  this.$on("getTime",function(h,m) {   //获取time-picker返回的点击后的数值,然后动态改变
   this.minutes = m;
   this.hour = h;
  })
 }
})

<time-box>组件

点击时、分的时候,要“通知”根实例点击的是什么,下面的时钟才能显示相应的数字。改变父组件的属性,有两种办法,一是直接修改父组件属性;二是通过自定义事件。

Vue.component('time-box',{
 template:'\
  <div class="timeBox" @click="openTime">\
   <span @click="changeCurrent(\'h\')">{{hour}}</span>\
   <span> : </span>\
   <span @click="changeCurrent(\'m\')">{{minutes}}<span/>\
  </div>',
 props: ['hour','minutes'],
 methods: {
  openTime: function() {
   app.$emit("openTimePicker");
  },
  changeCurrent: function(type) {
   if(type == 'h' ){
    app.current = 0;
   } else {
    app.current = 1;
   }
  }
 }
});

<time-picker>组件

这里最需要注意的就是单向数据流。时分是通过props传进来的,刚开始我直接操作this.hour,然后控制台警告。看到警告才想起看过的知识,这样很容易误改父组件的信息。所以啊,有些东西得实践才行,不能只看不敲。这里我定义一个局部 data 属性,并将 prop 的初始值作为局部数据的初始值。知识点:https://cn.vuejs.org/v2/guide/components.html#单向数据流

props: ['h','m','mode'],
data: function() {
 return {
  current: this.mode,
  hour: this.h,
  minutes: this.m
 }
},

正常情况下,如果时分不够两位数就要自动添加0,实现很简单的。刚开始直接判断是否小于10就添加。但是,“08”是小于10的,所以又自动添加0了。但是我觉得这里写得不好,还有改进的空间的。

//时分保证是两位数
fixHour: function() {
 return (this.hour < 10 && this.hour.toString().indexOf(0) !== 0) ? "0" + this.hour : this.hour
}
fixMinutes: function() {
 return (this.minutes < 10 && this.minutes.toString().indexOf(0) !== 0) ? "0" + this.minutes : this.minutes
},

再说说template里面的事吧。点击timepicker里面的时分改变组件的的current属性和透明度。这里显示数据就需要用到fixHour和fixMinutes了。

<div class="showtime">
 <span @click="current = 0" :style="{opacity: current == 0 ? 1 : 0.7}">{{fixHour(hour)}}</span>
 <span>:</span>
 <span @click="current = 1" :style="{opacity: current == 1 ? 1 : 0.7}">{{fixMinutes(minutes)}}</span>
</div>

圆盘里的内容就靠v-for了。先定义好12个位置,然后遍历每个位置。里面的针就通过CSS3的旋转啦。一共360度,12个格,一小时60分钟,这么简单的数字知识就不继续说下去了,下面的乘法我相信各位是看得懂的。这里注意的是60,我们钟表没有60只有0啊,所以 ((5 * i) % 60 || “00”)。这里写得很有技巧。60%60是0。然后是||和&&的问题了(推荐两本书《你不知道的JavaScript》上中卷,内容跟《高级程序设计JS》也不怎么重复,值得看)。0强转为false,然后||就返回第二个操作数的值。

<template>
 <div class="hourpicker">
   <div class="selector" :style="selectorRotateAngle()"></div>
   <span class="hourtxt" v-for="i in 12" :style="getHourStyle(i%12)" @click="current === 0 ? hour = i : minutes = ((5 * i) % 60 || \'00\')">{{current === 0 ? i : ((5 * i) % 60 || "00")}}</span>\
 </div>
</template>

methods: {
 //分时针的样式
 selectorRotateAngle: function(i) {
  if(this.current === 0) {
   return {
    transform: 'rotateZ('+(this.hour * 30)+'deg)'
   }
  } else {
   return {
    transform: 'rotateZ('+(this.minutes * 6)+'deg)'
   }
  }
 },
 //12格样式
 getHourStyle: function(i) {
  var hasSelected = (this.current === 0 && this.hour % 12 === i)
    || (this.current === 1 && this.minutes % 60 == (i * 5));  //判断到底是哪个数值被选中
  var styleObj = {
   transform: 'translate(' + positions[i][0] + "px, " + positions[i][1] + "px)",
   background: hasSelected ? 'rgb(0, 188, 212)' : 'rgba(255, 255, 255, 0)',
   color: !hasSelected ? '#2c3e50' : '#FFF'
  }
  return styleObj;
 }
}

最后就是把选好的数值传回给父组件啦。

//关闭timepicker
closePicker: function() {
 app.$emit('closeTimePicker');
},
 //获取时间
getTime: function() {
 app.$emit('getTime',this.fixHour(this.hour),this.fixMinutes(this.minutes));
 app.$emit('closeTimePicker');
}

v-ifv-show

v-show只是改变每次的display,而v-if如果为true才渲染到页面,所以每次隐藏显示都重新渲染一遍。我觉得。。。如果实际中,经常要开开关关的就用v-show就好了,但是用来v-show我发现不能根据选中的是时还是分来展现数值,很奇怪,v-if就可以。刚开始觉得是初始化问题,但是,既然hour和minute能根据props传下来再data转化,为啥mode就不行呢?没想明白。

在线demo:http://jsbin.com/dumace/2/edit?html,js,output

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

Javascript 相关文章推荐
Locate a File Using a File Open Dialog Box
Jun 18 Javascript
关于javascript 回调函数中变量作用域的讨论
Sep 11 Javascript
关于jQuery新的事件绑定机制on()的使用技巧
Apr 26 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
May 14 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
js实现的页面矩阵图形变换特效
Jan 26 Javascript
详解Vue路由History mode模式中页面无法渲染的原因及解决
Sep 28 Javascript
vue中的自定义分页插件组件的示例
Aug 18 Javascript
[jQuery] 事件和动画详解
Mar 05 jQuery
es6函数之尾递归用法实例分析
Apr 25 Javascript
微信小程序12行js代码自己写个滑块功能(推荐)
Jul 15 Javascript
JavaScript大数相加相乘的实现方法实例
Oct 18 Javascript
VueJS如何引入css或者less文件的一些坑
Apr 25 #Javascript
详解Angular 4.x 动态创建组件
Apr 25 #Javascript
Angular 4.x中表单Reactive Forms详解
Apr 25 #Javascript
Angular 4.x 动态创建表单实例
Apr 25 #Javascript
AngularJS动态菜单操作指令
Apr 25 #Javascript
Angular.js 4.x中表单Template-Driven Forms详解
Apr 25 #Javascript
详解JS中的attribute属性
Apr 25 #Javascript
You might like
php中使用Curl、socket、file_get_contents三种方法POST提交数据
2011/08/12 PHP
php通过COM类调用组件的实现代码
2012/01/11 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
2016/05/28 PHP
php实现URL加密解密的方法
2016/11/17 PHP
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
js动态生成指定行数的表格
2013/07/11 Javascript
js的2种继承方式详解
2014/03/04 Javascript
JS模拟键盘打字效果的方法
2015/08/05 Javascript
jQuery实现只允许输入数字和小数点的方法
2016/03/02 Javascript
详解JavaScript对象类型
2016/06/16 Javascript
jQuery实现鼠标选中文字后弹出提示窗口效果【附demo源码】
2016/09/05 Javascript
EasyUI学习之DataGird分页显示数据
2016/12/29 Javascript
JS实现直接运行html代码的方法
2017/03/13 Javascript
JS实现的透明度渐变动画效果示例
2018/04/28 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
React Native登录之指纹登录篇的示例代码
2020/11/03 Javascript
Python fileinput模块使用实例
2015/05/28 Python
python实现微信自动回复功能
2018/04/11 Python
python tkinter实现彩球碰撞屏保
2019/07/30 Python
关于python3中setup.py小概念解析
2019/08/22 Python
发现两个有趣的CSS3动画效果
2013/08/14 HTML / CSS
24个canvas基础知识小结
2014/12/17 HTML / CSS
基于canvas使用贝塞尔曲线平滑拟合折线段的方法
2018/01/10 HTML / CSS
使用postMessage让 iframe自适应高度的方法示例
2019/10/08 HTML / CSS
amazeui树节点自动展开折叠面板并选中第一个树节点的实现
2020/08/24 HTML / CSS
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
销售人员个人求职信
2013/09/26 职场文书
学生个人的自我评价分享
2013/11/05 职场文书
外语专业毕业生个人的自荐信
2013/11/19 职场文书
求职简历中自我评价
2014/01/28 职场文书
经典而简洁的婚礼主持词
2014/03/13 职场文书
父母寄语大全
2014/04/12 职场文书
世界遗产导游词
2015/02/13 职场文书
专业技术职务聘任证明
2015/03/02 职场文书
Redis如何一键部署脚本
2021/04/12 Redis