Vue自定义指令-实时时间转换指令 v-time开发
目錄
- 前言
- 1. 新建html、index.js文件
- 2. 時間轉換邏輯
- 3. 新建 time.js 文件
- 4 總結
前言
???????為了顯示出 實時性 ,在一些社交類產品中,比如WX朋友圈或微博等地方,作者發布動態的時間會實時顯示為“ 剛剛”、“ 1小時前”、“ 1天前” 等不同的格式。也就是一個相對本機時間轉換后的相對時間。這樣比直接轉換為年、月、日、時、分、秒更友好。本文記錄了實現這樣一個 自定義指令 v-time 的詳細過程。
1. 新建html、index.js文件
HTML
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>時間轉換指令</title> </head><body><div id="app"><div v-time="timeNow"></div><div v-time="timeBefore"></div></div><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src="./time.js"></script><script src="./index.js"></script> </body> </html>index.js
var app =new Vue({el :'#app',data : {// 當前時間戮(1970/01/01 至今的毫秒數)timeNow: (new Date()).getTime(),// (下面這個時間戳是毫秒級的,如服務端返回的秒級時間戳,則需要乘以1000)timeBefore: 1488930695721} }) ;timeNow 是目前的時間, timeBefore 是一個寫死的時間: 2017-03-08 。
2. 時間轉換邏輯
- 1 分鐘以前,顯示 “剛剛”。
- 1 分鐘~1 小時之間 ==> 顯示 “xx 分鐘前”;
- 1 小時~1 天之間 ==> 顯示 “xx 小時前”;
- 1 天~1 個月(31天)之間 ==> 顯示 “xx 天前” ;
- 大于 1 個月 ==> 顯示 “xx 年xx 月xx 曰”
3. 新建 time.js 文件
為了使判斷邏輯更簡單,統一使用時間戳進行大小判斷。
在寫指令v-time之前,需要先準備好與時間相關的函數,我們聲明一個對象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.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;},// 轉換時間 // 自定義指令 v-time 所需的,入參為毫秒級時間戳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;} }其中,getFormatTime() 方法就是自定義指令v-time所需要的、入參為毫秒級時間戳,該方法返回己整理好時間格式的字符串。
關于 JavaScript 的 Date 類型,詳情請參閱 >> MDN官方文檔 。
. 指令的注冊
指令跟組件一樣需要注冊才能使用,同樣有兩種方式,全局注冊和局部注冊。
1)全局注冊
Vue.directive('dirName',function(){//定義指令 });2)局部注冊
new Vue({ directives:{ dirName:{//定義指令 }} });3)v-time自定義指令注冊
本實例用全局注冊方式
Vue.directive('time', { bind: function(el, binding) { el.innerHTML = Time.getFormatTime(binding.value); // 定時器 el.__timeout__ 每分鐘觸發一次,更新時間el.__timeout__ = setInterval(function() { // 將格式化時間寫入指令所在元素el.innerHTML = Time.getFormatTime(binding.value);}, 60000); // 注意這里的60000是毫秒},unbind: function(el) {// 在 unbind 鉤子里清除定時器。clearInterval(el.__timeout__);delete el.__timeout__;} })在bind鉤子里, 將指令v-time表達式的值binding.value作為參數傳入Time.getFormatTime()方法得到格式化時間,再通過el.innerHTML寫入指令所在元素。定時器el. timeout每分鐘觸發一次,更新時間,并且在unbind鉤子里清除掉。
4 總結
??????在編寫 自定義指令 時,給 DOM 綁定一次性事件等初始動作,建議在 bind 鉤子內完成,同時要在unbind 內解除相關綁定。在自定義指令里,理論上可以任意操作 DOM,但這又違背 Vue.js 的初衷,所以對于大幅度的 DOM 變動,應使用組件。
【補充】:本例所用的時間戮都是毫秒級的,如服務端返回秒級時間戳,需要 乘以 1000 后再使用。
總結
以上是生活随笔為你收集整理的Vue自定义指令-实时时间转换指令 v-time开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习笔记之 创建节点 与 添加节点案
- 下一篇: 104. 二叉树的最大深度【LeetCo