文档开发者中心
我的

如何在快应用中自定义日期格式化组件

日期格式化组件简介

日期格式化组件通常用于需要展示友好的日期格式的场景。日期格式化组件具有如下特点:

  • 日期格式化组件可以显示基础时间。
  • 可以设置阀值,显示多久之前或者多久之后的时间。
  • 可以转换成英文。

日期格式化(dateformat)组件结构由text组成。布局结构如下图:

cke_305.png

布局代码如下:

cke_306.png

2.开发指引

2.1自定义子组件

日期格式化组件没有设置过多的样式,开发者可以自行添加。

子组件模板代码如下:

cke_307.png

子组件属性设计

支持的属性如下:

属性名

类型

默认值

说明

date

Object|String|Number

Date.now()

要格式化的日期对象/日期字符串/时间戳

threshold

Array

[0, 0]

转化类型阈值

format

String

yyyy/MM/dd hh:mm:ss

格式字符串

locale

Object

zh

格式化使用的语言,目前支持zh(中文)、en(英文)

注:threshold是用来控制转化的时间阈值的。

以[60000, 3600000]为例,将传入时间与当前时间差的绝对值记为delta(单位毫秒)

  • delta < 60000时,时间会被转化为“刚刚|马上”
  • delta >= 60000 && delta < 3600000时,时间会被转化为“xx分钟前|xx分钟后”,如果超过1小时会显示成“xx小时前|xx小时后”,以此类推
  • delta >= 3600000时,会按照format参数传入的格式进行格式化,如果不想转化为“马上|刚刚”可以传入threshold = "[0,3600000]"。默认值[0,0]既不会转换为“马上|刚刚”也不会转化为“xx分钟前|xx分钟后” 。

2.2 父子组件通信

子组件的props中定义相关属性值,父组件引用时传入属性值,子组件通过 this.xxx 获取值并进行处理。

cke_308.png

父组件给子组件传值,如果是布尔值,需要在data中定义,而不能直接在组件中定义。

父组件引用子组件代码如下:

cke_309.png

2.3计算数据和样式

使用计算属性computed方法,通过props属性动态计算数据和样式,返回给组件使用。下图中friendlyDate()方法是dateformat.js文件提供的一个方法。

cke_310.png

3.总结

实现日期格式化组件,您可以从中学会如下知识点:

  • 熟悉快应用子组件的设计和属性定义;
  • 公共能力如何独立成一个js文件供页面调用;
  • 日期相关操作。

想欲了解更多详情,请参见:

华为快应用官网资料:

最后附上完整的实现代码:

收藏日期格式化组件dateformat.ux

收起
自动换行
深色代码主题
复制

<template> <text>{{dateShow}}</text></template><script> /** * Dateformat 日期格式化 * @description 日期格式化组件 * @tutorial https://ext.dcloud.net.cn/plugin?id=3279 * @property {Object|String|Number} date 日期对象/日期字符串/时间戳 * @property {String} locale 格式化使用的语言 * @value zh 中文 * @value en 英文 * @property {Array} threshold 应用不同类型格式化的阈值 * @property {String} format 输出日期字符串时的格式absMs */ import { friendlyDate } from './dateformat.js' module.exports = { props: { date: { type: [Object, String, Number], default() { return Date.now() } }, locale: { type: String, default: 'zh', }, threshold: { type: Array, default() { return [0, 0] } }, format: { type: String, default: 'yyyy/MM/dd hh:mm:ss' }, }, computed: { dateShow() { return friendlyDate(this.date, { locale: this.locale, threshold: this.threshold, format: this.format }) } }, }</script>

dateformat.js:

收起
自动换行
深色代码主题
复制

function pad(str, length = 2) { str += '' while (str.length < length) { str = '0' + str } return str.slice(-length)}const parser = { yyyy: (dateObj) => { return pad(dateObj.year, 4) }, yy: (dateObj) => { return pad(dateObj.year) }, MM: (dateObj) => { return pad(dateObj.month) }, M: (dateObj) => { return dateObj.month }, dd: (dateObj) => { return pad(dateObj.day) }, d: (dateObj) => { return dateObj.day }, hh: (dateObj) => { return pad(dateObj.hour) }, h: (dateObj) => { return dateObj.hour }, mm: (dateObj) => { return pad(dateObj.minute) }, m: (dateObj) => { return dateObj.minute }, ss: (dateObj) => { return pad(dateObj.second) }, s: (dateObj) => { return dateObj.second }, SSS: (dateObj) => { return pad(dateObj.millisecond, 3) }, S: (dateObj) => { return dateObj.millisecond },}function formatDate(date, format = 'yyyy/MM/dd hh:mm:ss') { date = new Date(date) console.log("message123:"+date); const dateObj = { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate(), hour: date.getHours(), minute: date.getMinutes(), second: date.getSeconds(), millisecond: date.getMilliseconds() } const tokenRegExp = /yyyy|yy|MM|M|dd|d|hh|h|mm|m|ss|s|SSS|SS|S/ let flag = true let result = format while (flag) { flag = false result = result.replace(tokenRegExp, function (matched) { flag = true return parser[matched](dateObj) }) } return result}export function friendlyDate(time, { locale = 'zh', threshold = [60000, 3600000], format = 'yyyy/MM/dd hh:mm:ss'}) { if (time === '-') { return time } if (!time && time !== 0) { return '' } const localeText = { zh: { year: '年', month: '月', day: '天', hour: '小时', minute: '分钟', second: '秒', ago: '前', later: '后', justNow: '刚刚', soon: '马上', template: '{num}{unit}{suffix}' }, en: { year: 'year', month: 'month', day: 'day', hour: 'hour', minute: 'minute', second: 'second', ago: 'ago', later: 'later', justNow: 'just now', soon: 'soon', template: '{num} {unit} {suffix}' } } const text = localeText[locale] || localeText.zh let date = new Date(time) let ms = date.getTime() - Date.now() let absMs = Math.abs(ms) if (absMs < threshold[0]) { return ms < 0 ? text.justNow : text.soon } if (absMs >= threshold[1]) { return formatDate(date, format) } let num let unit let suffix = text.later if (ms < 0) { suffix = text.ago ms = -ms } //将数字向下舍入到最接近的整数Math.floor const seconds = Math.floor((ms) / 1000) const minutes = Math.floor(seconds / 60) const hours = Math.floor(minutes / 60) const days = Math.floor(hours / 24) const months = Math.floor(days / 30) const years = Math.floor(months / 12) switch (true) { case years > 0: num = years unit = text.year break case months > 0: num = months unit = text.month break case days > 0: num = days unit = text.day break case hours > 0: num = hours unit = text.hour break case minutes > 0: num = minutes unit = text.minute break default: num = seconds unit = text.second break } if (locale === 'en') { if (num === 1) { num = 'a' } else { unit += 's' } } return text.template.replace(/{\s*num\s*}/g, num + '').replace(/{\s*unit\s*}/g, unit).replace(/{\s*suffix\s*}/g, suffix)}

主页面hello.ux

收起
自动换行
深色代码主题
复制

<import name="dateformat" src="../Dateformat/dateformat"></import><template> <div class="container"> <text class="example-info">日期格式化组件,通常用于需要展示友好的日期格式的场景</text> <text>基础用法</text> <div class="example-body" > <dateformat date="{{now}}" ></dateformat> <dateformat date="2000/10/01 12:30:30"></dateformat> </div> <text>设置阈值</text> <text class="example-info">阈值用于控制什么时候显示刚刚|马上,什么时候显示xx分钟前|xx分钟后</text> <div class="example-body"> <dateformat date="{{now - 130000}}" threshold="{{[0,3600000]}}"></dateformat> <dateformat date="{{now - 130000}}" threshold="{{[0,0]}}"></dateformat> </div> <text>使用英文</text> <div class="example-body"> <dateformat date="{{now - 600000}}" threshold="{{[60000,3600000]}}" locale="en"></dateformat> <dateformat date="{{now - 30000}}" threshold="{{[60000,3600000]}}" locale="en"></dateformat> <dateformat date="{{now - 80000}}" threshold="{{[60000,3600000]}}" locale="en"></dateformat> </div> </div></template><script> export default { data() { return { now: Date.now() } }, }</script><style> .container { flex-direction: column; background-color: #efeff4; } text { font-size: 30px; line-height: 50px; } .example-info { padding: 15px; color: #3b4144; background-color: #ffffff; } .example-body { flex-direction: column; padding: 15px; background-color: #ffffff; height: 120px; }</style>

点赞
收藏
回复
3
分享
举报
浏览702 发布于2022-01-05 08:56未知归属地
全部评论
最多点赞
最新发布
最早发布

感谢楼主,文章写的很细,我悟了。

3楼回复于2022-01-25 14:03 未知归属地

不错,谢谢楼主讲解。

2楼回复于2022-01-24 11:26 未知归属地
向楼主学习了,楼主多来点
1楼回复于2022-01-06 08:28 未知归属地
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要发帖子

目录 收起
日期格式化组件简介
2.开发指引
2.1自定义子组件
2.2 父子组件通信
2.3计算数据和样式
3.总结
了解社区公约,与您携手共创和谐专业的开发者社区。