用Vue开发一个实时性时间转换功能,看这篇文章就够了
前言
最近有一个说法,如果你看见某个网站的某个功能,你就大概能猜出背后的业务逻辑是怎么样的,以及你能动手开发一个一毛一样的功能,那么你的前端技能算是进阶中高级水平了。比如咱们今天要聊的这个话题:如何用Vue开发一个实时性的时间转换指令?
接下来正文从这开始~

如上图所示(我是截取的某技术社区首页的部分页面),大家看到用红色边框勾选中的时间文字了吧。很多网站发布动态的时候,都会有一个相对本机时间转换后的相对时间。那你知道这个功能实现的背后原理是什么吗?如果有兴趣的,请备好瓜子,茶水,继续往下读。
一般在服务器的存储时间格式是Unix时间戳,比如 2018-01-17 06:00:00的时间戳是1516140000。前端在拿到数据后,将它转换为可持续的时间格式再显示出来。为了显示出实时性,在一些社交类产品中,甚至会实时转换为几秒前、几分钟前、几小时前等不同的格式,因为这样比直接转换为年、月、日、时、分、秒,显得对用户更加友好,体验更人性化。
今天,我们就来实现这样一个Vue自定义指令v-time,将表达式传入的时间戳实时转换为相对时间。为了便于演示效果,我们初始化时定义了两个时间。
首先来看html结构:
<div id="app" v-cloak>
<div v-time="timeNow"></div>
<div v-time="timeBefore"></div>
</div>
以及初始化一个Vue实例:
var app = new Vue({
el:'#app',
data:{
timeNow:(new Date()).getTime(),
timeBefore:686219755822
}
})
timeNow是目前的时间,timeBefore是一个写死的时间:1991-09-30。
先来分析一下时间转换的逻辑:
- 1分钟以前,显示“刚刚”。
- 1分钟~1小时之间,显示“xx分钟前”。
- 1小时~1天之间,显示“xx小时前”。
- 1天~1个月(31天)之间,显示“xx天前”。
- 大于1个月,显示“xx年xx月xx日”。
这样罗列出来,逻辑就一目了然了。为了使判断更简单,我们这里统一使用时间戳进行大小判断。在写指令v-time之前,需要先写一系列与时间相关的函数 ,我们声明一个对象Time,把它们都封装到里面。
var Time = {
//获取当前时间戳
getUnix:function(){
var date = new Date();
return date.getTime();
},
//获取今天0点0分0秒的时间戳
getTodayUnix:function(){
var date = new Date();
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
return date.getTime();
},
//获取今年1月1日0点0分0秒的时间戳
getYearUnix:function(){
var date = new Date();
date.setMonth(0);
date.setDate(1);
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
date.setMilliseconds(0);
return date.getTime();
},
//获取标准年月日
getLastDate:function(time){
var date = new Date(time);
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
return date.getFullYear() + '-' + month + '-' + day;
},
//转换时间
getFormatTime:function(timestamp){
var now = this.getUnix(); // 当前时间戳
var today = this.getTodayUnix(); // 今天0点的时间戳
var year = this.getYearUnix(); // 今年0点的时间戳
var timer = (now - timestamp) / 1000; // 转换为秒级时间戳
var tip = '';
if(timer <= 0){
tip = '刚刚';
}else if(Math.floor(timer/60) <= 0){
tip = '刚刚';
}else if(timer < 3600){
tip = Math.floor(timer/60) + '分钟前';
}else if(timer >= 3600 && (timestamp - today >= 0)){
tip = Math.floor(timer/3600) + '小时前';
}else if(timer/86400 <= 31){
tip = Math.ceil(timer/86400) + '天前';
}else{
tip = this.getLastDate(timestamp);
}
return tip;
}
}
当然,如果你对JavaScript的Date类型不太了解,可以先去runoob.com上面了解下。

接着说回来,Time.getFormatTime()方法就是自定义指令v-time所需要的,参数为毫秒级时间戳,返回已经整理好的时间格式的字符串。
最后,来看我们如何用Vue自定义一个指令v-time:
Vue.directive('time',{
bind:function(el, binding){
el.innerHTML = Time.getFormatTime(binding.value);
el.__timeout__ = setInterval(function(){
el.innerHTML = Time.getFormatTime(binding.value);
}, 60000)
},
unbind:function(el){
clearInterval(el.__timeout__);
delete el.__timeout__;
}
})
在bind钩子里,将指令v-time表达式的值binding.value作为参数传入Time.getFormatTime()方法中得到格式化时间,在通过el.innerHTML写入指令所在元素。定时器el.__timeout__每分钟触发一次,更新时间,并且在unbind钩子里清除掉。
你可能会问,这个binding.value是什么?
当然,你可以通过console.log(binding)方法在控制台打印一下,就一目了然了。

在这里,我先补充下,自定义指令的选项是由几个钩子函数组成的,有bind、insert、update、componentUpdated、unbind。而其中的bind和unbind只调用一次。每个钩子函数都有几个参数可用,比如我们上面用到的el和binding。
el指令所绑定的元素可以用来直接操作DOM。而binding是一个对象,包含很多属性,如上图所示:
- name:指令名
- rawName:自定义指令
- value:指令的绑定值
- expression:绑定值的字符串形式
- modifiers:一个包含修饰符的对象
总结
在编写自定义指令时,给DOM绑定一次性事件等初始动作,建议在bind钩子内完成,同时要在unbind内解除相关绑定。
后记
前端路漫漫,这是不真的事实。而我想说的是,无论前途多么遥远,我都希望你做一个志在四方的少年。
欢迎关注我的公众号:闰土大叔,我在那里等你。

用Vue开发一个实时性时间转换功能,看这篇文章就够了的更多相关文章
- Vue开发入门看这篇文章就够了
摘要: 很多值得了解的细节. 原文:Vue开发看这篇文章就够了 作者:Random Fundebug经授权转载,版权归原作者所有. 介绍 Vue 中文网 Vue github Vue.js 是一套构建 ...
- csdn上讲一个实时计算架构比较清晰的一篇文章
https://blog.csdn.net/ymh198816/article/details/51998085
- 用vue开发一个app(4,一个久等了的文章)H5直播平台登录注册(1)
我上一篇关于vue的文章和这一篇时间隔了有点久了.最近终于写完了. 因为我一直想写个有点实绩的东西,而不是随便写一个教程一样东西.结合最近在项目中学到的经验和我的一点创意. 首先介绍下这是个什么! H ...
- 【如何快速的开发一个完整的iOS直播app】(原理篇)
原文转自:袁峥Seemygo 感谢分享.自我学习 目录 [如何快速的开发一个完整的iOS直播app](原理篇) [如何快速的开发一个完整的iOS直播app](播放篇) [如何快速的开发一个完整的 ...
- 【如何快速的开发一个简单的iOS直播app】(代码篇)
开篇([如何快速的开发一个完整的iOS直播app](原理篇)) 好久没写简书,因为好奇的我跑去学习直播了,今天就分享一下我的感慨. 目前为止直播还是比较热点的技术的,简书,git上有几篇阅读量和含金量 ...
- 用vue开发一个公众号商城SPA——1.前期准备和写页面
使用vue开发公众号商城 第1篇记录项目准备.搭建,写页面遇到第问题以及总结,持续更新 公司最近接了个商城项目,包括PC端商城.微信公众号网页商城.后台管理系统.这几天在做微信公众号商城,又新接触了很 ...
- vue中插值表达式中时间转换yyyy-MM-dd HH:mm:ss
vue插值表达式中将时间转换两种方式:一.定义方法 <div id="app">当前实时时间:{{dateFormat(date)}}</div> //时间 ...
- 01 . Go之Gin+Vue开发一个线上外卖应用
项目介绍 我们将开始使用Gin框架开发一个api项目,我们起名为:云餐厅.如同饿了么,美团外卖等生活服务类应用一样,云餐厅是一个线上的外卖应用,应用的用户可以在线浏览商家,商品并下单. 该项目分为客户 ...
- 03 . Gin+Vue开发一个线上外卖应用(用户数据创建,插入,跨域处理)
功能和背景介绍 在项目的登录功能中,如果在登录时发现用户名和密码在用户表中不存在,会自动将用户名和密码保存在用户表中,创建一个新的用户. 因此,除了使用手机号和验证码登录以外,还支持使用用户名.密码进 ...
随机推荐
- linux 虚拟机模拟配置网络路由环境-简版
前言:网络路由不管是平常在家里,还是在公司中,都是必需配置的,所以还是非常重要的,今天小编就给大家做个配置网络路由配置的小实验,仅供大家参考. 一.首先,来简单介绍一下网络路由. 1. 网络路由: ...
- java两种动态代理方式的理解
要理解动态代理,不妨先来看看一个静态代理的例子. 一.静态代理 以一个电商项目的例子来说明问题,比如我定义了一个订单的接口IOrder,其中有一个方法时delivery,代码如下. package c ...
- String类为什么要用final修饰(面试回答)
String是所有语言中最常用的一个类.我们知道在Java中,String是不可变的.final的.Java在运行时也保存了一个字符串池(String pool),这使得String成为了一个特别的类 ...
- django+Python数据库利用Echarts实现网页动态数据显示
这几天一直在思考前端--服务器--数据库的之间的数据交互,最后决定了用django来做,为什么呢?因为我这只是在开发阶段,所以就用了django自带的web服务器(很方便)而且呢,它还自带了数据库sq ...
- JS获取字符对应的ASCII码
有时候会需要用到字符的ASCII码,一时之间调试时可能会忘记字符与ASCII码对应的数字. 最近喜欢用浏览器控制台直接跑JS代码,将这个代码直接贴到浏览器控制台,即可调试(谷歌浏览器快捷键 ctrl+ ...
- JavaScript循环实例
几个经典的循环案例: 1.一张纸的厚度是0.0001米,将纸对折,对折多少次厚度超过珠峰高度8848米 var i=0; var h=0.0001; while(true){ i++; h=h*2; ...
- OC学习15——文件I/O体系
OC提供了丰富的I/O相关API,如果只是管理文件和目录,程序可以使用NSFileManager进行管理,包括创建.删除.移动和复制文件等:如果程序需要读取文件内容,则可通过NSFileHandle进 ...
- Win10关闭某程序的通知的方法
一.点击右下角的通知图标. 二.点击所有通知. 三.点击系统 四.点击通知和操作 五.下拉,看到:获取来自这些发送者的通知 六.关闭自己想关闭通知的程序即可.
- UWP 使用OneDrive云存储2.x api(二)【全网首发】
接上一篇 http://www.cnblogs.com/hupo376787/p/8032146.html 上一篇提到为了给用户打造一个完全无缝衔接的最佳体验,UWP开发者最好也要实现App设置和数据 ...
- 本机向windows服务器传输文件的三种方法
闲来无事,在腾讯云上申请了一个免费的服务器,想将自己写的网页发布到服务器上,服务器的申请很简单,百度搜索 腾讯云 ,然后新人第一次注册能申请到免费一个月的云主机,虽然配置不怎么高,但是还是能用的,这是 ...