当前位置:首页 > JavaScript

js实现模板引擎

2026-01-30 22:07:43JavaScript

实现简单模板引擎

使用字符串替换方法实现基础模板引擎功能。定义一个模板字符串,通过占位符标记需要替换的部分,利用正则表达式匹配占位符并进行替换。

function simpleTemplate(template, data) {
  return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
    return data[key] || '';
  });
}

const template = 'Hello, {{name}}! Today is {{day}}.';
const data = { name: 'Alice', day: 'Monday' };
console.log(simpleTemplate(template, data)); // Hello, Alice! Today is Monday.

处理复杂表达式

扩展模板引擎以支持对象属性访问和简单表达式。通过更复杂的正则表达式匹配模板中的JavaScript表达式,并使用Function构造函数动态执行。

js实现模板引擎

function advancedTemplate(template, data) {
  return template.replace(/\{\{(.+?)\}\}/g, (match, exp) => {
    try {
      return new Function('data', `with(data){return ${exp}}`)(data);
    } catch {
      return '';
    }
  });
}

const template = 'User: {{user.name}}, Age: {{user.age + 1}}';
const data = { user: { name: 'Bob', age: 25 } };
console.log(advancedTemplate(template, data)); // User: Bob, Age: 26

实现条件渲染

添加条件判断支持,使用特殊语法标记条件块。通过正则表达式分割模板字符串,解析条件逻辑并决定是否渲染特定部分。

function conditionalTemplate(template, data) {
  const ifRegex = /\{\{if\s+(.+?)\}\}(.+?)\{\{\/if\}\}/gs;
  return template.replace(ifRegex, (match, condition, content) => {
    const test = new Function('data', `with(data){return !!(${condition})}`)(data);
    return test ? content : '';
  });
}

const template = '{{if user.admin}}Admin Access{{/if}}';
const data1 = { user: { admin: true } };
const data2 = { user: { admin: false } };
console.log(conditionalTemplate(template, data1)); // Admin Access
console.log(conditionalTemplate(template, data2)); // (空字符串)

实现循环渲染

支持数组遍历功能,解析循环语法并重复渲染模板片段。处理数组数据时,为每次迭代创建新的上下文。

js实现模板引擎

function loopTemplate(template, data) {
  const eachRegex = /\{\{each\s+(\w+)\s+as\s+(\w+)\}\}(.+?)\{\{\/each\}\}/gs;
  return template.replace(eachRegex, (match, arrayName, itemName, content) => {
    const array = new Function('data', `with(data){return ${arrayName}}`)(data) || [];
    return array.map(item => {
      return content.replace(/\{\{(\w+)\}\}/g, (m, key) => {
        return item[key] || '';
      });
    }).join('');
  });
}

const template = '{{each users as user}}<li>{{user.name}}</li>{{/each}}';
const data = { users: [{ name: 'Alice' }, { name: 'Bob' }] };
console.log(loopTemplate(template, data)); // <li>Alice</li><li>Bob</li>

缓存编译模板

优化性能,预先编译模板为可执行函数。将模板字符串转换为函数并缓存,减少重复解析的开销。

const templateCache = {};

function compileTemplate(template) {
  if (templateCache[template]) return templateCache[template];

  const code = `with(data){return \`${template
    .replace(/\{\{if\s+(.+?)\}\}/g, '`;$1?`')
    .replace(/\{\{\/if\}\}/g, '`:``')
    .replace(/\{\{each\s+(\w+)\s+as\s+(\w+)\}\}/g, '`;${$1}.map($2=>`')
    .replace(/\{\{\/each\}\}/g, '`).join("")+`')
    .replace(/\{\{(.+?)\}\}/g, '${$1}')
  }\`}`;

  templateCache[template] = new Function('data', code);
  return templateCache[template];
}

function cachedTemplate(template, data) {
  const render = compileTemplate(template);
  return render(data);
}

const template = '{{if show}}Hello{{/if}} {{each items as item}}{{item}}{{/each}}';
const data = { show: true, items: [1, 2, 3] };
console.log(cachedTemplate(template, data)); // Hello 123

安全考虑

避免使用with语句可能带来的安全问题,改用更安全的上下文处理方式。限制可访问的变量,防止原型污染。

function safeTemplate(template, data) {
  const allowed = new Set(Object.keys(data));
  const sandbox = Object.create(null);

  Object.keys(data).forEach(key => {
    Object.defineProperty(sandbox, key, {
      enumerable: true,
      get: () => data[key]
    });
  });

  const code = `return \`${template
    .replace(/\{\{(.+?)\}\}/g, '${$1}')
  }\``;

  try {
    return new Function('sandbox', code).call(null, sandbox);
  } catch {
    return '';
  }
}

const template = 'Hello {{name}}! {{toString}}';
const data = { name: 'Charlie' };
console.log(safeTemplate(template, data)); // Hello Charlie! 

标签: 模板引擎
分享给朋友:

相关文章

vue实现a4打印模板

vue实现a4打印模板

使用Vue实现A4打印模板 在Vue中实现A4打印模板需要结合CSS的打印样式和Vue的模板渲染能力。以下是具体实现方法: 设置A4纸张尺寸 在CSS中定义A4纸张的标准尺寸(210mm × 297…

CSS模板网站制作

CSS模板网站制作

CSS模板网站制作指南 CSS模板网站制作涉及多个关键步骤,从设计到实现,以下为详细方法: 选择模板或框架 使用现成的CSS框架如Bootstrap、Tailwind CSS或Foundation可…

vue模板实现

vue模板实现

Vue 模板实现 Vue 模板是 Vue.js 的核心特性之一,用于声明式地将数据渲染到 DOM 中。以下是 Vue 模板的实现方式和常见用法。 基本语法 Vue 模板使用 HTML 的模板语法,可…

vue模板功能实现

vue模板功能实现

Vue 模板功能实现 Vue 的模板功能是 Vue.js 的核心特性之一,允许开发者通过声明式的方式将数据绑定到 DOM。以下是 Vue 模板功能的主要实现方式和相关技术细节。 插值语法 Vue…

jquery实现vue模板

jquery实现vue模板

jQuery 实现类似 Vue 模板功能 在传统 jQuery 项目中模拟 Vue 的模板和数据绑定功能,可以通过以下方式实现: 数据绑定与模板渲染 使用 jQuery 的 .html() 或 .…

vue实现模板导入

vue实现模板导入

Vue 实现模板导入的方法 在 Vue 项目中实现模板导入功能,可以通过多种方式实现,具体取决于需求场景(如文件上传、动态加载组件等)。以下是几种常见实现方案: 使用动态组件导入模板 通过 Vue…