本文共 2930 字,大约阅读时间需要 9 分钟。
简单模板模式是一种通过格式化字符串拼接来生成视图的技术,旨在减少视图层面上的节点操作,从而解决数据与结构的强耦合性问题。与模板方法模式相比,它更注重技术实现的简洁性和灵活性。
在传统的节点操作中,生成列表往往涉及繁琐的DOM操作。例如:
const list = [ { name: 'Google', url: 'https://www.google.com' }, { name: 'Baidu', url: 'https://www.baidu.com' }, { name: 'Bing', url: 'https://cn.bing.com' }];const root = document.getElementById('root');const ul = document.createElement('ul');list.forEach((item) => { const li = document.createElement('li'); const a = document.createElement('a'); a.href = item.url; a.target = '_blank'; a.innerText = item.name; li.appendChild(a); ul.appendChild(li);});root.appendChild(ul); 这种方法虽然功能上可行,但当数据规模扩大时,代码的可读性和维护性会显著下降。
为了减少节点操作的复杂性,开发者常常采用字符串拼接的方式。例如:
const template = `
这种方法虽然简化了操作,但由于字符串与数据的强耦合,一旦数据或结构发生变化,整个视图就需要重新生成,导致维护成本上升。
为了进一步提升代码的可读性,开发者引入了模板渲染的概念。通过将数据格式化到模板字符串中,实现视图的渲染。例如:
const formatString = (str, data) => { return str.replace(/\{\{(\w+)\}\}/g, (match, key) => data[key]);};const template = [' 这种方法通过动态替换模板字符串,显著提升了代码的可读性和维护性。
为了更灵活地处理模板语法,开发者常常使用模板引擎。例如,可以通过以下方法实现简单的模板语法:
function render(element, data) { const originString = element.innerHTML; let html = originString .replace(/"/g, '\\\"') .replace(/\s+/g, ' ') .replace(/\{\{(.+?)\}\}/g, (match, key) => data[key]); html = `var targetHTML = "${html}";return targetHTML;`; const parsedHTML = new Function(...Object.keys(data))(...Object.values(data)); element.innerHTML = parsedHTML;} 通过这种方式,开发者可以在模板字符串中嵌入多种数据字段,并在需要时动态替换内容。
为了进一步优化模板渲染过程,开发者可以采用AST(抽象语法树)解析的方式。例如:
function parseAST(root) { const node = { parent: null, type: 'tag', tagName: root.localName, children: [], attr: {} }; Array.from(root.attributes).forEach(item => { node.attr[item.name] = item.value; }); Array.from(root.childNodes).forEach(child => { const childNode = parseAST(child); childNode.parent = node; node.children.push(childNode); }); return node;}function generateHTMLTemplate(AST) { let template = ''; function traverse(node) { if (node.type === 'tag') { template += `<${node.tagName}>`; traverse(node.children[0]); traverse(node.children[1] || node.children[2] || node.children[3]); template += ` `; } else { template += node.content; } } traverse(AST); return template;}const root = document.getElementById('root');const ast = parseAST(root);const template = generateHTMLTemplate(ast);render(root, template, data); 这种方式通过解析模板字符串为AST,进一步提升了渲染效率,特别是在数据频繁变动的情况下。
GitHub - WindrunnerMax/EveryDay