优化实战 第 42 期 - 前端如何高效的生成唯一ID

6,108 阅读2分钟

UUID.png

技术背景

前端在做一些业务逻辑的时候,通常会使用一个唯一标识作为数据的 key 值,而有时候数据本身并没有这个唯一标识,使用下标的话又会引发一些隐藏的 Bug

甚至说在给后端传递集合数据的时候,会要求前端给他传递一个 ID 字段,真是打心底里服,不过这都不是事儿

唯一识别码(UUID)

  • 构成

    由一组 32 位数的 16 进制数字构成

  • 格式

    以连字号分为五段,表现形式为 8-4-4-4-1232 个字符,第三段的第一个数值标识其版本

  • 示例

    5717a297-07a3-4a27-829e-ae773bdde275

使用开源包生成

  • 安装

    npm install uuid 
    
  • 创建

    import { v4 as uuidv4 } from 'uuid'
    const uuid = () => uuidv4().replace(/-/g, '')
    
  • 说明

    使用基于随机数的 V4 版本,也是 UUID 使用最多的

基于 Blob 和 URL 对象生成

  • 掌握 window.URL.createObjectURL 的使用

    用来将 blob 或 file 对象读取成一个 url

    const objUrl = window.URL.createObjectURL(object)
    

    返回一个在内存中指向传入参数 object 的引用路径(url字符串),它可以用在 html 中任何可以使用 url 的地方,如 img 的 src、audio/video 的 src 等

    这个引用路径在当前页面的 document 被销毁的时候失效,也可以通过以下方法手动销毁

    window.URL.revokeObjectURL(objUrl)
    
  • 方法封装

    const uuid = () => {
      const blobUrl = URL.createObjectURL(new Blob())
      URL.revokeObjectURL(blobUrl)
      return blobUrl.slice(blobUrl.lastIndexOf('/') + 1).replace(/-/g, '')
    }
    

其于 Crypto API 生成

  • 原生方法生成

    const uuid = () => crypto.randomUUID().replace(/-/g, '')
    

    使用加密安全随机数生成器生成 v4 UUID,且此方法仅在安全上下文 HTTPS 中可用

  • 浏览器兼容性

    randomUUID.jpg

  • 通过 外观模式 解决兼容性

    const uuid = () => {
      let uniqueId = null
      try {
        uniqueId = crypto.randomUUID()
      } catch {
        const blobUrl = URL.createObjectURL(new Blob())
        URL.revokeObjectURL(blobUrl)
        uniqueId = blobUrl.slice(blobUrl.lastIndexOf('/') + 1)
      }
      return uniqueId.replace(/-/g, '')
    }
    

应用场景

  • 面临问题

    使用上传功能时,如果用户上传了同名文件就会出现覆盖的情况

  • 解决方案

    生成唯一ID,在保留原有文件名称和扩展名的情况下生成新的唯一名称

    例如:ccfc356df3dc4330a0379a0e06645673_上传的图片.jpg