使用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实现带节日和农历的日历特效
Feb 01 Javascript
CSS javascript 结合实现悬浮固定菜单效果
Aug 23 Javascript
JavaScript实现类似淘宝的购物车效果
Mar 16 Javascript
用 js 的 selection range 操作选择区域内容和图片
Apr 18 Javascript
详解angular 中的自定义指令之详解API
Jun 20 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
Jan 17 Javascript
VUE2.0+Element-UI+Echarts封装的组件实例
Mar 02 Javascript
vue基于element的区间选择组件
Sep 07 Javascript
JavaScript常见事件处理程序实例总结
Jan 05 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
Aug 03 Javascript
在实例中重学JavaScript事件循环
Dec 03 Javascript
一篇文章弄清楚Ajax请求的五个步骤
Mar 17 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实现懒加载的方法
2015/03/07 PHP
php统计数组元素个数的方法
2015/07/02 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
PHP+redis实现微博的推模型案例分析
2019/07/10 PHP
雄兵连第三季海报曝光,艾妮熙德成主角,蔷薇新造型
2021/03/09 国漫
Jquery 学习笔记(一)
2009/10/13 Javascript
向大师们学习Javascript(视频与PPT)
2009/12/27 Javascript
Ajax异步提交表单数据的说明及方法实例
2013/06/22 Javascript
jQuery分组选择器用法实例
2014/12/23 Javascript
NodeJS Web应用监听sock文件实例
2015/02/18 NodeJs
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
原生js实现节日时间倒计时功能
2017/01/18 Javascript
Vue实现动态显示textarea剩余字数
2017/05/22 Javascript
实时监控input框,实现输入框与下拉框联动的实例
2018/01/23 Javascript
Vue.js实现的表格增加删除demo示例
2018/05/22 Javascript
Javascript实现异步编程的过程
2018/06/18 Javascript
解决layer弹层遮罩挡住窗体的问题
2018/08/17 Javascript
详解vue-cli脚手架中webpack配置方法
2018/08/22 Javascript
Vue源码解析之数组变异的实现
2018/12/04 Javascript
vue自定义指令的创建和使用方法实例分析
2018/12/04 Javascript
highCharts提示框中显示当前时间的方法
2019/01/18 Javascript
layui关闭弹窗后刷新主页面和当前更改项的例子
2019/09/06 Javascript
[01:07:19]2018DOTA2亚洲邀请赛 4.5 淘汰赛 Mineski vs VG 第一场
2018/04/06 DOTA
Python微医挂号网医生数据抓取
2019/01/24 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
代码实例讲解python3的编码问题
2019/07/08 Python
Python zip函数打包元素实例解析
2019/12/11 Python
pytorch 指定gpu训练与多gpu并行训练示例
2019/12/31 Python
Python对wav文件的重采样实例
2020/02/25 Python
python 利用Pyinstaller打包Web项目
2020/10/23 Python
HTML5 canvas实现雪花飘落特效
2016/03/08 HTML / CSS
澳大利亚第一的设计师礼服租赁网站:GlamCorner
2017/08/13 全球购物
Bose加拿大官方网站:美国知名音响品牌
2019/03/21 全球购物
打架检讨书2000字
2014/02/22 职场文书
领导党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
JAVA API 实用类 String详解
2021/10/05 Java/Android