VueUse 中的 useTimeAgo 函数的国际化和浏览器内置国际化API

看到一个帖子提到了 VueUse 中的一个函数 useTimeAgo,比较好奇这个函数是干什么的就点开了帖子看了一下。
其实就是一个相对时间对比的函数,输入一个目标时间(允许时间戳或者格式化日期字符串),返回目标距离现在的文本内容。

举个例子:

import { useTimeAgo } from '@vueuse/core'

useTimeAgo(new Date()) // just now
useTimeAgo(new Date('2024-06-01')) // 2 weeks ago

但是 useTimeAgo 函数返回的文本内容是固定的英文字符串。所以,如果在中文环境下使用就可能会被挑战说需要展示中文的相对时间文本。
🔗 vueuse/packages/core/useTimeAgo/index.ts at main · vueuse/vueuse

看了一下 useTimeAgo 的实现,是支持自己做一份国际化配置,然后传入给 useTimeAgo 方法来使用的。

阅读全文

HTTP缓存限制 和 Service Worker

一直以来只知道 HTTP Cache 是有缓存总量上限的,但是不知道对于单个文件的体积大小也是有限制的。

在这次接盘的3D可视化项目中就遇到了这个问题。因为模型文件体积比较大,在实际使用中经常会反馈说载入时间过长。所以在拿到服务器权限之后就改了一下 Nginx 的配置文件开启了静态资源的 HTTP cache,以为完事大吉就和一线说载入时间慢的问题解决好了。现在进入项目会使用本地缓存,在第一次载入的时候会慢一些,后面再次进入就会快很多了。

但是实际使用中反馈过来的时依旧会有很长的载入时间。以为是 Nginx 的配置项写错了,就又去确认了一下。确实是开启了缓存的,首页的各种静态资源也是会被缓存,但是等我进入到模型展示页的时候就发现问题了!
最外层展示的模型是可以被缓存的,但是操作数据下钻之后开始展示内部模型从 Network 面板中看到的 glb 模型文件不是每一个都会从 disk cache 读取,有一些模型依旧会发起请求。

面板截图

所以就想着浏览器是不是可以有配置项可以修改,但是并没有(可以通过给快捷方式添加启动命令来修改,但不可能要求所有设备都这样做)。所以只能想其他法子来解决这个问题,自然就找到了 Service Worker

阅读全文

生成UUID的方法 Crypto.randomUUID()

对于我这种比较懒的人,一直以来都是直接用 new Date().valueOf() 或者 Math.random() 配合一些规则来生成唯一ID,不配置规则的话,出现重复的概率还是比较高的。前几天看到群里有人说起了这个新的API(也不新了21年夏天发布的了)就大概看了一下。

各个主流浏览器也都支持了。不过呢,开始支持的版本都比较高🔗 “randomUUID” | Can I use
所以在一些不喜欢更新软件版本的用户里面就会抛出错误比如说 "crypto" is not defined 或者 crypto.randomUUID is not a function

阅读全文

记 RegExp.test() 方法使用全局匹配时一会返回 true 一会返回 false 的问题

今天小伙伴问了一个奇怪的问题,他在使用 RegExp.test() 方法时使用全局匹配时会依次返回 truefalse 的现象。
比如说:

var t = /#/g
t.test("#")
// true
t.test("#")
// false
t.test("#")
// true
t.test("#")
// false

我一开始以为是他正则写的不对,让他把其它的匹配规则都去掉再试试,结果问题还是依旧。
后来让他把 /gg 去掉试了下发现没问题了。但还是没有怀疑到全局匹配的问题上,以为是他哪里覆写掉了的 test() 方法。让他使用空白页测试,依旧有这样的问题。

阅读全文

JS中的数字格式化和大位数缩写

以前因为项目需要 i18n ,一直以来都是自己写了一个格式化函数来处理,会使用 replace 配合正则对数字进行千位分割来展示,并且搭配 Vue.filter 来实现快速格式化。
但是对于大位数处理就会比较麻烦了,因为在境内就需要使用 万位分割,大位数使用 万、亿、万亿 来缩,而在英语系国家就会使用 千分分隔,比如说: K、M、B 来缩写数额。

正巧最近开始了一个需要国际化的项目,在一开始编写数字格式化过滤器的时候偶尔发现了 Intl.NumberFormat().format() 这个API,原来现在 原生JS就支持了对数字的格式化,并且不光可以千位分隔,还可以将大位数缩写。

阅读全文

JS中的字符串前后补全(补位)

在日常项目中经常会遇到需要对字符串补位的操作,比如

  • 向前补0:例如日期,经常会需要YYYY-MM-DD 的格式,
    如果不使用日期库,直接获取月份和日期前面是没有0的,需要手动拼接字符串。

正巧今天要搞日历组件,前面缺一个0总感觉少了点感觉,当时懒得自己写补全了,想着百度一个吧,就搜到了张鑫旭大佬的这篇文章 《JS字符串补全方法padStart()和padEnd()简介》,然后就惊了,原来早在4年前 JS 就原生支持了前后补全了(我这几年在干嘛😢)

阅读全文

数组的 .map() 和 .forEach() 是否会修改原数组

面试的时候也算是进场会遇到的一个题目了,结论就是 可以也不可以,看原始数据是什么结构的,也看你如何是操作的。

如果说数组元素是基本类型的,比如说是数字类型、字符串、布尔类型的,那么不管是用 .map() 还是 .forEach() 都是无法修改原数组的。
如果说是集合类型的,比如说数组、对象,那么直接操作内部的元素或者属性都是会修改原数组的。

阅读全文

如何判定一个变量是数组

一个不幸的消息,最近我厂因为资金的问题凉凉了,所以我得开始重新找工作了,最近应该会分享一些和面试题有关并且我觉得有意思的内容,
😁 正巧今天面试的时候被问到的一个面试题我觉得就挺有意思的题目:

你如何判断一个变量是数组?

因为得知公司要解散的消息后比较仓促,也就没有好好刷面试题直接就出去面了(无缝衔接实属渣男了),所以被问道这还算是比较经典面试题的时候,下意识就回答了使用 typeof 来判断,但是想起来不对啊,数组他是对象类型嘛!

😱 卧槽,踩坑里了。

就马上补充了一句:“emmmm….好像用 typeof 不行,数组返回的是 Object ,应该可以通过原型链上的 constructor 来判断….噢,通过 instanceof 也可以!”

不出意料因为踩坑了,紧接着面试官就追问了一句 “还有其它的方式吗?”
考虑了5秒左右答 “没有了,暂时想不起来更多的方式。”,面试官回:“还有一种 isArray 可以判断”

以前一直没有考虑过这种问题,去判断一个对象是否为数组的场景。所以我觉得就还蛮有意思的,所以回来之后想看看还有哪几种方式可以判断是否为数组。

阅读全文

原型链! __proto__ 与 prototype

Every JavaScript object has a second JavaScript object (or null ,but this is rare) associated with it. This second object is known as a prototype, and the first object inherits properties from the prototype.
每个 JavaScript 对象都会对应一个原型对象(除了 null),并从原型对象继承属性和方法。
JavaScript 权威指南

一句话解释:对象 __proto__ 属性是JS内置的,它所对应值是原型对象的 prototype ;而 prototype 就是你自己写的原型属性、方法 加上 JS原型内置的属性、方法

阅读全文

JS中的 new 关键字做了什么?

new 运算符 创建 一个用户定义的 对象类型 的实例或 具有构造函数的内置对象 的实例。

完整的了解 new 运算符你可能还需要了解一下 面向对象思想 以及 原型链,可以简单查看这篇笔记 👉 原型链! __proto__ 与 prototype

如果快速的了解 new 关键字按照MDN的文档描述来说就是:

  1. new关键字会创建一个空的简单JavaScript对象(即 {});
  2. 链接该对象(设置该对象的 constructor)到另一个对象 (绑定原型);
  3. 步骤1 新创建的对象作为 this 的上下文 ;
  4. 如果该函数没有返回对象,则返回 this

可以简单理解成 new 关键字帮我们处理了书写构造函数时一些固定的步骤

阅读全文