浅谈在Vue.js中如何实现时间转换指令


Posted in Javascript onJanuary 06, 2019

在社区中,发布的动态信息,经常会有一个相对余实际发布时间的相对时间。比如这里的微博:

浅谈在Vue.js中如何实现时间转换指令

服务端存储的时间格式,一般为 Unix 时间戳,比如 2019/1/6 13:40:1 的Unix 时间戳为 1546753201651。前端在获取到这个时间戳之后,会转换为可读格式的时间。在社交类产品中,一般会将时间戳转换为 x 分钟前,x 小时前或者 x 天前,因为这样的显示方式用户体验更好。

我们可以自定义一个 v-relative-time 指令来实现上述功能。

html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style type="text/css">

  </style>
</head>
<body>

  <div id="app" v-cloak>
    现在时间:<div v-relative-time="now"></div><p></p>
    2019/1/6 13:45:02:<div v-relative-time="1546753502000"></div><p></p>
    2019/1/6 8:02:02:<div v-relative-time="1546732922000"></div><p></p>
    2019/1/5 22:02:02:<div v-relative-time="before"></div><p></p>
    2019/1/1 22:02:02:<div v-relative-time="1546351322000"></div><p></p>
    2018/1/6 8:02:02:<div v-relative-time="1515196922000"></div>
  </div>


<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
<script src="index.js"></script>
</body>
</html>

注意:div v-relative-time 指令的入参为精确到毫秒的 Unix 时间戳,如果入参单位为秒,那么可以乘以 1000 后,再传入。

js:

/**
 * 时间对象
 * @type {{getCurrentUnix: Time.getCurrentUnix, getTodayUnix: Time.getTodayUnix, getThisYearUnix: Time.getThisYearUnix, format: Time.format, compensateZero: Time.compensateZero, transform: Time.transform}}
 */
var Time = {
  //获取当前 Unix 时间戳
  getCurrentUnix: function () {
    return new Date().getTime();
  },
  //获取今日 0 点 0 分 0 秒的 Unix 时间戳
  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 秒的 Unix 时间戳
  getThisYearUnix: 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();
  },
  //格式化日期;输出格式为 xxxx-xx-xx
  format: function (val) {
    var dateObj = new Date(val);
    //month 代表月份的整数值从0(1月)到11(12月),所以需要转换
    var month = this.compensateZero(dateObj.getMonth() + 1);
    var day = this.compensateZero(dateObj.getDate());
    return dateObj.getFullYear() + '-' + month + '-' + day;
  },
  /**
   * 如果值小于 10,那么在前面补一个零
   * @param val
   * @returns {*}
   */
  compensateZero: function (val) {
    if (typeof val == 'number') {
      return val < 10 ? '0' + val : val;
    } else {
      return val;
    }
  },
  /**
   * 转换为相对时间
   *
   * 1 分钟之前,返回“刚刚”
   * 1 分钟到 1 小时之间,返回“xx 分钟前”
   * 1 小时到 1 天之间,返回“xx 小时前”
   * 1 天到 1 个月(假设固定为 31 天)之间,返回“xx 天前”
   * 大于 1 个月,返回“xx 年 xx 月 xx 日”
   * @param val unix 时间戳
   */
  transform: function (val) {
    //计算时间间隔(单位:s)
    console.log("getCurrentUnix:" + this.getCurrentUnix());
    var interval = (this.getCurrentUnix() - val) / 1000;

    if (Math.floor(interval / 60) <= 0) {//1 分钟之前
      return '刚刚';
    } else if (interval < 3600) {//1 分钟到 1 小时之间
      return Math.floor(interval / 60) + ' 分钟前';
    } else if (interval >= 3600 && (val - this.getTodayUnix() >= 0)) {//1 小时到 1 天之间
      return Math.floor(interval / 3600) + ' 小时前';
    } else if (interval / (3600 * 24) <= 31) {//1 天到 1 个月(假设固定为 31 天)之间
      return Math.ceil(interval / (3600 * 24)) + ' 天前';
    } else {
      return this.format(val);
    }
  }

};

时间转换逻辑为:

  1. 如果是 1 分钟之前,返回“刚刚”
  2. 如果是 1 分钟到 1 小时之间,返回“xx 分钟前”
  3. 如果是 1 小时到 1 天之间,返回“xx 小时前”
  4. 如果是 1 天到 1 个月(假设固定为 31 天)之间,返回“xx 天前”
  5. 如果是大于 1 个月,返回“xx 年 xx 月 xx 日”

我们专门设计了一个 Time 对象,用于定义与时间相关的函数:

  1. 获取当前 Unix 时间戳。
  2. 获取今日 0 点 0 分 0 秒的 Unix 时间戳。
  3. 获取今年 1 月 1 日 0 点 0 分 0 秒的 Unix 时间戳。
  4. 格式化日期函数,输出格式为 xxxx-xx-xx。
  5. 如果值小于 10,那么在前面补一个零的格式化函数。
  6. 转换为相对时间。

以下是与时间相关的小知识:

Math.floor()
Math.ceil()
/**
 * 相对时间指令
 */
Vue.directive('relative-time', {
  bind: function (el, binding) {
    el.innerHTML = Time.transform(binding.value);
    el._relativeTime = setInterval(function () {
      el.innerHTML = Time.transform(binding.value);
    }, 60000);//每分钟,刷新一次
  },
  unbind: function (el) {
    clearInterval(el._relativeTime);
    delete el._relativeTime;
  }
});

var app = new Vue({
  el: '#app',
  data: {
    now: (new Date()).getTime(),
    //2019/1/5 22:02:02
    before: 1546696922000
  }
});

在相对时间指令中,我们在 bind() 中,把指令中的入参转换为相对时间,然后写入指令所在的元素中,接着还定义了一个每分钟更新元素内容的定时器。在 unbind() 中,执行清除定时器操作。

渲染结果:

浅谈在Vue.js中如何实现时间转换指令

编写自定义指令,建议如下:

  1. 在 bind() 中定义初始化操作,比如绑定一次性事件。
  2. 在 unbind() 中定义解绑与删除操作。
  3. 虽然可以在自定义指令中任意操作 DOM,但这就不是数据驱动 DOM 啦,所以遇到这样的场景,建议使用组件来满足业务要求。

本文示例代码

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

Javascript 相关文章推荐
Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
Apr 26 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
Jun 15 Javascript
JavaScript算法系列之快速排序(Quicksort)算法实例详解
Sep 04 Javascript
关于vue.js弹窗组件的知识点总结
Sep 11 Javascript
微信小程序商城项目之淘宝分类入口(2)
Apr 17 Javascript
利用Vue2.x开发实现JSON树的方法
Jan 04 Javascript
webpack4 SCSS提取和懒加载的示例
Sep 03 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
Feb 19 jQuery
微信小程序实现页面分享onShareAppMessage
Aug 12 Javascript
vue.js的状态管理vuex中store的使用详解
Nov 08 Javascript
Node.JS获取GET,POST数据之queryString模块使用方法详解
Feb 06 Javascript
原生JS实现九宫格抽奖
Sep 13 Javascript
浅谈Vue.js中如何实现自定义下拉菜单指令
Jan 06 #Javascript
react-router4按需加载(踩坑填坑)
Jan 06 #Javascript
React 实现拖拽功能的示例代码
Jan 06 #Javascript
Next.js实现react服务器端渲染的方法示例
Jan 06 #Javascript
vue.js引入外部CSS样式和外部JS文件的方法
Jan 06 #Javascript
Bootstrap4 gulp 配置详解
Jan 06 #Javascript
jQuery实现获取当前鼠标位置并输出功能示例
Jan 05 #jQuery
You might like
网友原创的PHP模板类代码
2008/09/07 PHP
phpmyadmin里面导入sql语句格式的大量数据的方法
2010/06/05 PHP
《PHP编程最快明白》第八讲:php启发和小结
2010/11/01 PHP
ThinkPHP CURD方法之limit方法详解
2014/06/18 PHP
检测codeigniter脚本消耗内存情况的方法
2015/03/21 PHP
php简单获取文件扩展名的方法
2015/03/24 PHP
PHP 根据key 给二维数组分组
2016/12/09 PHP
为何说PHP引用是个坑,要慎用
2018/04/02 PHP
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
多个js与css文件的合并方法详细说明
2012/12/26 Javascript
js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)
2013/02/02 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
2015/02/04 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
用javascript实现自动输出网页文本
2015/07/30 Javascript
Javascript 引擎工作机制详解
2016/11/30 Javascript
Mongoose中document与object的区别示例详解
2017/09/18 Javascript
浅谈Vue-cli单文件组件引入less,sass,css样式的不同方法
2018/03/13 Javascript
详解Angular-ui-BootStrap组件的解释以及使用
2018/07/13 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
jquery实现进度条状态展示
2020/03/26 jQuery
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
如何在vue中使用kindeditor富文本编辑器
2020/12/19 Vue.js
python使用webbrowser浏览指定url的方法
2015/04/04 Python
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
Python 专题五 列表基础知识(二维list排序、获取下标和处理txt文本实例)
2017/03/20 Python
对numpy的array和python中自带的list之间相互转化详解
2018/04/13 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
2018/04/30 Python
python实现微信自动回复机器人功能
2019/07/11 Python
python 画图 图例自由定义方式
2020/04/17 Python
通过自学python能找到工作吗
2020/06/21 Python
Python爬虫爬取新闻资讯案例详解
2020/07/14 Python
企业军训感想
2014/02/07 职场文书
北京英文导游词
2015/02/12 职场文书
超详细教你怎么升级Mysql的版本
2021/05/19 MySQL
ubuntu安装jupyter并设置远程访问的实现
2022/03/31 Python