基于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 相关文章推荐
jQuery 开天辟地入门篇一
Dec 09 Javascript
JavaScript mapreduce工作原理简析
Nov 25 Javascript
JavaScript调试工具汇总
Dec 23 Javascript
基于jQuery实现选取月份插件附源码下载
Dec 28 Javascript
JavaScript实现简单的tab选项卡切换
Jan 05 Javascript
微信小程序 form组件详解
Oct 25 Javascript
easyui form validate总是返回false的原因及解决方法
Nov 07 Javascript
React组件的三种写法总结
Jan 12 Javascript
vue项目动态设置页面title及是否缓存页面的问题
Nov 08 Javascript
微信小程序 可搜索的地址选择实现详解
Aug 28 Javascript
node.js处理前端提交的GET请求
Aug 30 Javascript
JS this关键字在ajax中使用出现问题解决方案
Jul 17 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
广播爱好者需要了解的天线知识
2021/03/01 无线电
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
2012/01/12 PHP
php中Snoopy类用法实例
2015/06/19 PHP
PHP添加图片水印、压缩、剪切的封装类
2015/08/17 PHP
php微信公众平台交互与接口详解
2016/11/28 PHP
常用PHP封装分页工具类
2017/01/14 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
2019/08/23 PHP
css把超出的部分显示为省略号的方法兼容火狐
2008/07/23 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
jQuery中:only-child选择器用法实例
2015/01/03 Javascript
解决js页面滚动效果scrollTop在FireFox与Chrome浏览器间的兼容问题的方法
2015/12/03 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
javascript用正则表达式过滤空格的实现代码
2016/06/14 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
echarts饼图扇区添加点击事件的实例
2017/10/16 Javascript
vue实现滑动到底部加载更多效果
2020/10/27 Javascript
vue实现倒计时获取验证码效果
2020/04/17 Javascript
JS合并两个数组的3种方法详解
2019/10/24 Javascript
Vue.js 无限滚动列表性能优化方案
2019/12/02 Javascript
js实现踩五彩块游戏
2020/02/08 Javascript
基于脚手架创建Vue项目实现步骤详解
2020/08/03 Javascript
详解Howler.js Web音频播放终极解决方案
2020/08/23 Javascript
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
2020/12/24 Javascript
Python入门篇之对象类型
2014/10/17 Python
利用Python破解验证码实例详解
2016/12/08 Python
python下如何查询CS反恐精英的服务器信息
2017/01/17 Python
Python魔法方法详解
2019/02/13 Python
python小项目之五子棋游戏
2019/12/26 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
加拿大折扣、优惠券和交易网站:WagJag
2018/02/07 全球购物
英国家庭家具、照明和花园家具购物网站:Furniture123
2018/12/31 全球购物
公路局群众路线教育实践活动第一阶段工作汇报
2014/10/25 职场文书
个人先进材料范文
2014/12/30 职场文书
2016会计专业自荐信范文
2016/01/28 职场文书
话题作文之财富(600字)
2019/12/03 职场文书
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/06 PostgreSQL