Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 21x 21x 21x 21x 13x 13x 3x 4x 7x 21x 12x 9x 4x 9x 4x 5x 21x 5x | import { toSingleLineString } from './toSingleLineString' export interface StringTemplateRenderOptions { /** 是否启用代码渲染,需环境支持 eval */ code?: boolean /** 是否仅代码渲染 */ onlyCode?: boolean } /** * 字符串模板。 */ export class StringTemplate { /** * 渲染字符串模板。语法: * * - 用 `{key}` 直接替换; * - 用 `{key#10}` 直接替换,取前10个字符省略; * - 用 `{key:param1,param2}` 执行函数替换; * - 用 `{{key==='test'?'hi':'hello'}}` 执行代码替换(内部使用 eval 实现,需开启选项里的 `code` 参数)。 * * @param template 要渲染的模板 * @param data 渲染数据 * @param options 渲染选项 * @returns 返回渲染后字符串 */ static render( template: string, data: Record<string, any>, options?: StringTemplateRenderOptions, ) { const onlyCode = !!options?.onlyCode const enableCode = onlyCode || !!options?.code const keys = Object.keys(data) if (!onlyCode) { for (const key of keys) { template = typeof data[key] === 'function' ? template.replace( new RegExp(`\\{${key}(:.+?)?\\}`, 'g'), (_, params: string) => { return data[key].call( null, ...(params ? params.substring(1) : '').split(','), ) }, ) : enableCode ? template.replace( new RegExp(`(?<!\\$)\\{${key}(?:#(\\d+))?\\}`, 'g'), (_, len) => len ? toSingleLineString(String(data[key]), +len) : data[key], ) : template.replace( new RegExp(`{${key}(?:#(\\d+))?\\}`, 'g'), (_, len) => len ? toSingleLineString(String(data[key]), +len) : data[key], ) } } if (enableCode) { template = template.replace(/\{\{(.+?)\}\}/g, (_, code) => { // 需在 eval 里函数两边加上括号才能返回函数 const res = eval(`(function (data) { ${keys.map(key => `var ${key} = data["${key}"];`).join('')} return ${code}; })`)(data) if (res == null || res === true || res === false) { return '' } return res }) } return template } /** 判断是否有代码块 */ static hasCodeBlock(template: string): boolean { return /\{\{(.+?)\}\}/.test(template) } } |