如何在快应用中自定义日期格式化组件
日期格式化组件简介
日期格式化组件通常用于需要展示友好的日期格式的场景。日期格式化组件具有如下特点:
- 日期格式化组件可以显示基础时间。
- 可以设置阀值,显示多久之前或者多久之后的时间。
- 可以转换成英文。
日期格式化(dateformat)组件结构由text组成。布局结构如下图:

布局代码如下:

2.开发指引
2.1自定义子组件
日期格式化组件没有设置过多的样式,开发者可以自行添加。
子组件模板代码如下:

子组件属性设计
支持的属性如下:
| 属性名 | 类型 | 默认值 | 说明 |
| 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 获取值并进行处理。

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

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

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未知归属地
全部评论
最多点赞
最新发布
最早发布
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
- 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
- 如您发布的内容为转载内容,请注明内容来源。
我要发帖子
目录 收起
日期格式化组件简介
2.开发指引
2.1自定义子组件
2.2 父子组件通信
2.3计算数据和样式
3.总结
了解社区公约,与您携手共创和谐专业的开发者社区。








































苏公安网备 32011402010933号