Note.03-Snippets代码片段

本文汇总了多种前端开发中实用的技巧与算法,包括数组处理、日期格式化、文件操作等,帮助开发者提高效率。

001 Fisher–Yates Shuffle 洗牌算法

const shuffle = (arr) => {
  let i = arr.length
  let j
  while (i) {
    j = Math.floor(Math.random() * i--)
    ;[arr[i], arr[j]] = [arr[j], arr[i]]
  }
  return arr
}

002 数字千分位格式化

const toThousandFilter = (num) => {
  return (+num || 0).toString().replace(/^-?\d+/g, (m) => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}

003 日期格式化

const parseTime = (time, format = '{y}-{m}-{d} {h}:{i}:{s}') => {
  if (arguments.length === 0) return null
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string' && /^[0-9]+$/.test(time)) {
      time = parseInt(time)
    }
    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

004 动态加载 JS 文件

const loadJS = (url) => {
  return new Promise((resolve) => {
    const recaptchaScript = document.createElement('script')
    recaptchaScript.setAttribute('src', url)
    recaptchaScript.async = true
    recaptchaScript.onload = () => resolve()
    document.head.appendChild(recaptchaScript)
  })
}

const loadAssets = async () => {
  const assets = [
    'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js',
    'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js',
  ]

  for (const url of assets) {
    await loadJS(url)
  }
}

005 动态下载文件

const downloadFile = (file) => {
  fetch(file.url).then((res) =>
    res.blob().then((blob) => {
      const a = document.createElement('a')
      const url = window.URL.createObjectURL(blob)
      a.href = url
      a.download = file.name
      a.click()
      window.URL.revokeObjectURL(url)
    })
  )
}

006 获取文件扩展名

const getFileExt = (filename) => {
  return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2)
}

007 创建独一无二字符串

const createUniqueString = () => {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

008 事件绑定与解绑

/**
 * @description 绑定事件 on(element, event, handler)
 */
const on = (function () {
  if (document.addEventListener) {
    return function (element, event, handler) {
      if (element && event && handler) {
        element.addEventListener(event, handler, false)
      }
    }
  } else {
    return function (element, event, handler) {
      if (element && event && handler) {
        element.attachEvent('on' + event, handler)
      }
    }
  }
})()

/**
 * @description 解绑事件 off(element, event, handler)
 */
const off = (function () {
  if (document.removeEventListener) {
    return function (element, event, handler) {
      if (element && event) {
        element.removeEventListener(event, handler, false)
      }
    }
  } else {
    return function (element, event, handler) {
      if (element && event) {
        element.detachEvent('on' + event, handler)
      }
    }
  }
})()

009 获取视频时长

const getVideoDuration = () => {
  const fileObj = this.$refs.file.files[0]
  const video = document.createElement('video')
  video.preload = 'metadata'
  video.onloadedmetadata = () => {
    window.URL.revokeObjectURL(video.src)
    const duration = video.duration
  }
  video.src = URL.createObjectURL(fileObj)
}

010 判断是否重复操作

const isRepeat = (function () {
  const reData = {}
  return function (name = 'default', time = 300) {
    const now = new Date()
    const re = now - (isNaN(reData[name]) ? 0 : reData[name])
    reData[name] = now
    return re <= time
  }
})()

011 Chunk array

长数组按指定长度拆分为嵌套子数组:

const chunk = (arr, size) => Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(size * i, size * i + size))
chunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]

012 DeepFlatten

多层嵌套数组展开:

const deepFlatten = (arr) => [].concat(...arr.map((v) => (Array.isArray(v) ? deepFlatten(v) : v)))
deepFlatten([1, [2, 3], [[4, 5], 6]]) // [1, 2, 3, 4, 5, 6]

013 获取路由参数

如果项目有使用 vue-router 的话,最简单的方式是取 this.$route.query。但是有些项目并没有使用 vue-router,这时可以使用 URLSearchParams

//  url = "https://xxxx.com?a=1&b=2"
const searchParams = new URLSearchParams(window.location.search)
searchParams.has('a') === true // true
searchParams.get('a') === '1' // true
searchParams.getAll('a') // ["1"]
searchParams.append('c', '3') // "a=1&b=2&c=3"
searchParams.toString() // "a=1&b=2&c=3"
searchParams.set('a', '0') // "a=0&b=2&c=3"
searchParams.delete('a') // "b=2&c=3"

由于 URLSearchParams 的兼容性,老旧浏览器兼容可以使用下面代码:

function getQueryString(name) {
  var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
  var r = location.search.substr(1).match(reg)
  if (r != null) {
    return decodeURIComponent(r[2])
  }
  return null
}

014 获取路由参数对象

const param2Obj = (url) => {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"').replace(/\+/g, ' ') + '"}')
}

015 构建 FormData 表单

const formBuilder = (obj) => {
  const formData = new FormData()
  Object.keys(obj).forEach((k) => {
    formData.append(k, obj[k])
  })
  return formData
}

016 AES 加解密

const CryptoJS = require('crypto-js')

const key = CryptoJS.enc.Utf8.parse('1234123412ABCDEF') // 密钥
const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412') // 密钥偏移量

/**
 * 消息加密
 * @param {*} msg
 */
export const encodeMsg = (msg) => {
  const msgStr = JSON.stringify(msg)
  const srcs = CryptoJS.enc.Utf8.parse(msgStr)
  const encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  })
  const encryptedStr = encrypted.ciphertext.toString()
  return encryptedStr
}

/**
 * 消息解密
 * @param {*} msgStr
 */
export const decodeMsg = (msgStr) => {
  const encryptedHexStr = CryptoJS.enc.Hex.parse(msgStr)
  const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr)
  const decrypt = CryptoJS.AES.decrypt(srcs, key, {
    iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  })
  const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
  return decryptedStr.toString()
}

017 求差集

// const difference = [users, unUsed].reduce((a, b) => a.filter(c => !b.includes(c)))

const diff = (arr) => {
  return arr.reduce((a, b) => a.filter((c) => !b.includes(c)))
}
diff([[1, 2, 3], [2, 3], [3]]) // [1]

018 去除 HTML 标签

正则表达式

export const removeHtmlTag = (raw) => raw.replace(/<[\s\S]+?>/g, '')

DOM API

export const removeHtmlTag = (raw) => {
  const box = document.createElement('template')
  box.innerHTML = raw
  return box.content.textContent
}

019 判断合法日期

export const isDate = (raw) => !isNaN(+new Date(raw))

利用 Date 构造函数内部的算法,对于无法解析为日期的数据,date.toString() 会返回 Invalid Datedate.getTime() 对应的返回值则是 NaN。而算数运算符会调用对象的 valueOf() 方法,date.valueOf() 的返回值又与 date.getTime() 相同。

020 全局跨域配置

@Configuration
public class CorsConfig {

    /**
     * 允许跨域调用的过滤器
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许跨越发送cookie
        config.setAllowCredentials(true);
        // 允许所有域名进行跨域调用
        config.addAllowedOrigin("*");
        // 放行全部原始头信息
        config.addAllowedHeader("*");
        // 允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

}

021 获取泛型 class

private Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

022 ReflectionToStringBuilder

通过反射打印对象:

System.out.println(ReflectionToStringBuilder.toString(umsAdmin, ToStringStyle.MULTI_LINE_STYLE));

023 赋值判断

line = bufferedReader.readLine()) != null 先赋值再比较,然后就可以使用变量输出 System.out.println(line);,不需要执行两次 bufferedReader.readLine()

String line;
while ((line = bufferedReader.readLine()) != null) {
    System.out.println(line);
}

024 日期清空时分秒

private Date convertTime(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTime();
}

025 HttpServletRequest

@GetMapping("{id}")
public String reg(HttpServletRequest request, @PathVariable long id) {
    System.out.println("url" + request.getRequestURI());
    TbUser tbUser = tbUserMapper.selectByPrimaryKey(id);
    return tbUser.getUsername();
}

026 HashMap to List

HashMap<String, OrderAmount> OrderAmountHashMap = new HashMap<>();
List<String> axis = OrderAmountHashMap.keySet().stream().sorted().collect(Collectors.toList());
List<OrderAmount> list = new ArrayList<OrderAmount>(OrderAmountHashMap.values());

027 List Stream 索引下标

List<Date> dateList = getDateListOfDay();
List<String> axis = IntStream.range(0, dateList.size())
        .mapToObj(i -> DateFormat.format(dateList.get(i)))
        .collect(Collectors.toList());

028 读取并创建临时文件

InputStream stream = FileUtil.class.getClassLoader().getResourceAsStream("media/" + mobileconfig);
File targetFile = new File("media/" + System.currentTimeMillis() + ".mobileconfig");
FileUtils.copyInputStreamToFile(stream, targetFile);
return targetFile;

029 模板文件替换

private static File template() {
    Map<String, String> map = new HashMap<>();
    map.put("image_url", imageUrl);
    map.put("app_name", appName);
    map.put("official_url", officialUrl);

    InputStream stream = FileUtil.class.getClassLoader().getResourceAsStream("media/" + mobileconfig);
    File targetFile = new File("media/" + System.currentTimeMillis() + ".mobileconfig");
    StringSubstitutor sub = new StringSubstitutor(map);

    try {
        Reader fr = new InputStreamReader(stream);
        BufferedReader reader = new BufferedReader(fr);
        FileWriter fw = new FileWriter(target);
        BufferedWriter writer = new BufferedWriter(fw);
        String str;
        while ((str = reader.readLine()) != null) {
            String newStr = sub.replace(str);
            writer.write(newStr);
            writer.newLine();
        }
        writer.flush();
        writer.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return target;
}

原文引自:金点网络/数媒派 作者:jamin

以下是专为 **Verilog 注释** 设计的、可直接在 **Sublime Text** 中使用的代码片段Snippets)集合,帮助你快速插入标准化、结构化的注释块,提升代码可读性和开发效率。 这些 `.sublime-snippet` 文件基于 XML 格式编写,保存后即可通过快捷触发词 + Tab 自动生成常用注释模板。 --- ## ✅ 一、Verilog 注释类代码片段(推荐收藏使用) ### 📄 片段 1:模块头注释模板(输入 `hdr` + Tab) > 用于文件开头,描述模块基本信息 ```xml <snippet> <content><![CDATA[ //============================================================================ // Module Name : ${1:module_name}.v // Author : ${2:YourName} // Description : ${3:Brief function of the module} // Date : ${TM_YEAR}-${TM_MONTH}-${TM_DATE} // Revision : v1.0 // Usage : ${4:Integrated in top-level or standalone} // Notes : ${5:Active-low reset, sync enable} //============================================================================ $0 ]]></content> <tabTrigger>hdr</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] Module Header</description> </snippet> ``` 📌 效果: ```verilog //============================================================================ // Module Name : counter.v // Author : zhangsan // Description : 8-bit up counter with enable // Date : 2025-04-05 // Revision : v1.0 // Usage : Used in timer control block // Notes : Clock is 50MHz, reset is active high //============================================================================ ``` --- ### 📄 片段 2:功能区划分注释(输入 `sec` 或 `com` + Tab) > 分隔不同逻辑区域,如“Input Logic”、“FSM”等 ```xml <snippet> <content><![CDATA[ //======================================== // $1 //======================================== $0 ]]></content> <tabTrigger>sec</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] Section Divider</description> </snippet> ``` 📌 示例用法: ```verilog //======================================== // State Machine Control Logic //======================================== always @(posedge clk) ... ``` --- ### 📄 片段 3:信号说明注释(输入 `sig` + Tab) > 快速为 wire/reg 添加方向和功能说明 ```xml <snippet> <content><![CDATA[ // [${1:I/O}] ${2:signal_name} - ${3:Signal purpose, e.g., "data valid pulse"} $0 ]]></content> <tabTrigger>sig</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] Signal Description</description> </snippet> ``` 📌 示例: ```verilog // [I] clk - System clock input (50MHz) // [I] rst_n - Active-low reset // [O] done - Pulse when operation completes ``` --- ### 📄 片段 4:TODO 待办事项注释(输入 `tdo` + Tab) ```xml <snippet> <content><![CDATA[ // TODO(${1:user}): ${2:Add feature or fix issue} $0 ]]></content> <tabTrigger>tdo</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] TODO Note</description> </snippet> ``` 📌 示例: ```verilog // TODO(zhangsan): Optimize timing for setup slack ``` 💡 提示:大多数编辑器能高亮显示 `TODO`,便于后期追踪。 --- ### 📄 片段 5:FSM 状态说明注释(输入 `fsm` + Tab) ```xml <snippet> <content><![CDATA[ /* * FSM States: * ${1:current_state} [ ${2:IDLE } = 2'b00 : ${3:Wait for start signal}, ${4:RUN } = 2'b01 : ${5:Transfer data phase}, ${6:DONE } = 2'b10 : ${7:Finalize and report} * ] */ $0 ]]></content> <tabTrigger>fsm</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] FSM State Documentation</description> </snippet> ``` 📌 可视化状态编码与含义,方便调试和文档生成。 --- ### 📄 片段 6:单行简洁注释(输入 `cmt` + Tab) ```xml <snippet> <content><![CDATA[ // $1 $0 ]]></content> <tabTrigger>cmt</tabTrigger> <scope>source.verilog,source.systemverilog</scope> <description>[Comment] Inline Comment</description> </snippet> ``` 📌 比直接打 `//` 更规范,适合团队统一风格。 --- ## ✅ 二、如何安装这些 Snippets? ### 步骤如下: 1. 打开 Sublime Text 2. 菜单栏选择: ``` Tools → Developer → New Snippet... ``` 3. 将上面任一 XML 内容粘贴进去 4. 修改 `<tabTrigger>` 和内容后,保存为: ``` Packages/User/verilog_hdr.sublime-snippet ``` (路径可通过 `Preferences → Browse Packages` 进入) 5. 重启或立即生效!在 `.v` 文件中输入触发词 + `Tab` 即可展开。 --- ## ✅ 三、推荐触发词汇总表 | 触发词 | 功能 | 推荐用途 | |--------|------|----------| | `hdr` | 模块头部信息 | 文件第一行 | | `sec` | 区域分隔线 | 划分逻辑块 | | `sig` | 信号说明 | 定义 reg/wire 后 | | `tdo` | TODO 标记 | 遗留问题跟踪 | | `fsm` | 状态机说明 | FSM 设计时 | | `cmt` | 快速单行注释 | 日常注释 | --- ## ✅ 四、高级技巧:支持自动变量填充 Sublime 支持以下动态变量: | 变量 | 含义 | |------|------| | `${TM_YEAR}` | 当前年份(2025) | | `${TM_MONTH}` | 月份(04) | | `${TM_DATE}` | 日期(05) | | `${env:USER}` | 系统用户名 | | `$filename` | 当前文件名 | 👉 示例增强版头部可用: ```xml // Author: ${env:USER} // Date : ${TM_YEAR}-${TM_MONTH}-${TM_DATE} ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值