使用Vue开发一个实时性时间转换指令


Posted in Javascript onJanuary 17, 2018

前言

最近有一个说法,如果你看见某个网站的某个功能,你就大概能猜出背后的业务逻辑是怎么样的,以及你能动手开发一个一毛一样的功能,那么你的前端技能算是进阶中高级水平了。比如咱们今天要聊的这个话题:如何用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上面了解下。

使用Vue开发一个实时性时间转换指令

接着说回来,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)方法在控制台打印一下,就一目了然了。

使用Vue开发一个实时性时间转换指令

在这里,我先补充下,自定义指令的选项是由几个钩子函数组成的,有bind、insert、update、componentUpdated、unbind。而其中的bind和unbind只调用一次。每个钩子函数都有几个参数可用,比如我们上面用到的el和binding。

el指令所绑定的元素可以用来直接操作DOM。而binding是一个对象,包含很多属性,如上图所示:

  • name:指令名
  • rawName:自定义指令
  • value:指令的绑定值
  • expression:绑定值的字符串形式
  • modifiers:一个包含修饰符的对象

总结

在编写自定义指令时,给DOM绑定一次性事件等初始动作,建议在bind钩子内完成,同时要在unbind内解除相关绑定。

以上所述是小编给大家介绍的使用Vue开发一个实时性时间转换功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript 一些用法小结
Sep 11 Javascript
JavaScript面向对象设计二 构造函数模式
Dec 20 Javascript
js实现简单的验证码
Dec 25 Javascript
JS表单数据验证的正则表达式(常用)
Feb 18 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
Mar 08 Javascript
jQuery实现鼠标响应式透明度渐变动画效果示例
Feb 13 jQuery
VSCode中如何利用d.ts文件进行js智能提示
Apr 13 Javascript
解决linux下node.js全局模块找不到的问题
May 15 Javascript
浅谈Vue组件及组件的注册方法
Aug 24 Javascript
vue-router源码之history类的浅析
May 21 Javascript
详解微信小程序工程化探索之webpack实战
Apr 20 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
Jul 31 Javascript
angularjs 页面自适应高度的方法
Jan 17 #Javascript
VueJs监听window.resize方法示例
Jan 17 #Javascript
详解AngularJS之$window窗口对象
Jan 17 #Javascript
React-native桥接Android原生开发详解
Jan 17 #Javascript
vue自定义指令directive实例详解
Jan 17 #Javascript
移动web开发之touch事件实例详解
Jan 17 #Javascript
详解layui弹窗父子窗口之间传参数的方法
Jan 16 #Javascript
You might like
php中定义网站根目录的常用方法
2010/08/08 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
PHP中in_array的隐式转换的解决方法
2018/03/06 PHP
jquery 必填项判断表单是否为空的方法
2008/09/14 Javascript
jquery实现带复选框的表格行选中删除时高亮显示
2013/08/01 Javascript
在jquery中的ajax方法怎样通过JSONP进行远程调用
2014/04/04 Javascript
浅析Javascript中bind()方法的使用与实现
2016/04/29 Javascript
javascript 小数乘法结果错误的处理方法
2016/07/28 Javascript
浅析Javascript ES6新增值比较函数Object.is
2016/08/24 Javascript
第一次接触神奇的Bootstrap
2016/10/14 Javascript
JavaScript 值类型和引用类型的初次研究(推荐)
2017/07/19 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
js与jQuery实现的用户注册协议倒计时功能实例【三种方法】
2017/11/09 jQuery
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
关于TypeScript模块导入的那些事
2018/06/12 Javascript
JavaScript实现表单注册、表单验证、运算符功能
2018/10/15 Javascript
vue elementui el-form rules动态验证的实例代码详解
2019/05/23 Javascript
vue 取出v-for循环中的index值实例
2019/11/09 Javascript
[11:27]《一刀刀一天》之DOTA全时刻20:TI4总奖金突破920W TS赛事分析
2014/06/18 DOTA
[06:20]2015国际邀请赛第三日top10
2015/08/08 DOTA
Python中规范定义命名空间的一些建议
2016/06/04 Python
Python爬虫实现百度图片自动下载
2018/02/04 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
python3下实现搜狗AI API的代码示例
2018/04/10 Python
django反向解析和正向解析的方式
2018/06/05 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
将matplotlib绘图嵌入pyqt的方法示例
2020/01/08 Python
Python基于QQ邮箱实现SSL发送
2020/04/26 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
Python实现自动签到脚本的示例代码
2020/08/19 Python
Python 远程开关机的方法
2020/11/18 Python
美国气象仪器、花园装饰和墙壁艺术商店:Wind & Weather
2019/05/29 全球购物
Fox Racing英国官网:越野摩托车和山地自行车服装
2020/02/26 全球购物
森林防火宣传标语
2014/06/27 职场文书
班子群众路线教育实践个人对照检查材料思想汇报
2014/09/30 职场文书
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis