介绍

本文打算将出一个系列,循序渐进的探索 mustache 模板引擎的实现机理,大致分为 3 篇,将在 1-2 周内完成,分别为:

  1. 源起——讲述在没有模板引擎的时代我们是怎样操作 DOM 的
  2. mustache 的简单使用
  3. mustache 在 webpack 中的实现核心

本篇的话会讲述 3 种原始的操作 DOM 的方式—— JS 操作 DOM、数组 join 实现、模板字符串实现。至于 mustache,它是开创了数据与模板分离的鼻祖。

JS 操作 DOM

本质:是通过 JS 方式操作真实 DOM,需要不断创建元素,并添加至指定的元素内部,可看简单实现:

// 要挂载节点
<div id="container"></div>

// js 代码
const bBox = document.getElementById('container')

const data = [
  { name: 'zxn', age: 18, sex: '男' },
  { name: 'zyh', age: 18, sex: '女' }
]

for (let i = 0; i < data.length; i++) {
  const div = document.createElement('div') // 创建一个元素
  div.innerText = data[i].name + '的基础信息' // 因为要使用比较复古的方式去实现一个元素的内容,所以并没有使用解构和模板字符串方法

  const ul = document.createElement('ul')
  const li = document.createElement('li')
  li.innerText = '姓名:' + data[i].name
  ul.appendChild(li)

  const li2 = document.createElement('li')
  li2.innerText = '年龄:' + data[i].age
  ul.appendChild(li2)

  const li3 = document.createElement('li')
  li3.innerText = '性别:' + data[i].sex
  ul.appendChild(li3)

  bBox.appendChild(div)
  bBox.appendChild(ul)
}

可以看到,我们实现一个简单的 div + ul>li*3 的数据结构至少要创建 5 个标签,添加 5 处内容,如果说再加上一层嵌套则会更加麻烦,于是数组 join 的方式应运而出

数组 join 方式

本质:解决传统方式中要添加一个元素需要创建元素,添加内容、属性、追加至指定元素内部的问题,先看一个基础的例子:

// 挂载节点
<div id="container"></div>

// js 代码
const jDom =  [
  '哈哈,看到了吗,我换行了',
  '<div>某某的信息</div>',
  '<ul>',
  '  <li>姓名:某某</li>',
  '  <li>年龄:18</li>',
  '  <li>性别:男</li>',
  '</ul>'
].join('')

document.getElementById('container').innerHTML = jDom

可以看到通过 join 拼接的方式后,一是解决了在定义一个变量指定的代码块不能换行的问题,这让我们的代码结构清晰可见,且不需要我们再一个个创建元素,最后拼接为一个字符串后可直接挂载到节点上,更方便快捷。
在此基础上,实现一个循环嵌套的例子:

// 同样,挂载节点
<div id="container"></div>

// js 代码
const data = [
  { name: 'zxn', age: 18, sex: '男' },
  { name: 'zyh', age: 18, sex: '女' }
]

const mDom = document.getElementById('container')

for (let i = 0; i < data.length; i++) {
  mDom.innerHTML += [
    '<p>' + data[i].name + '的基础信息</p>',
    '<ul>',
    '  <li>姓名:' + data[i].name + '</li>', // 同样是使用了拼接的方式,如果再加上解构会更加便捷
    '  <li>年龄:' + data[i].age + '</li>',
    '  <li>性别:' + data[i].sex + '</li>',
    '</ul>'
  ].join('')
}

可以看到这样的书写相当于加隔断,需要注意隔断两端的符号要一致,且还需要每一行都需要加上单引号,书写起来虽然美观些,但还是有些麻烦,于是模板字符串出现了。

模板字符串实现

本质:可换行,可直接在需要的地方引入变量,更便捷,看简单实现:

// 挂载节点
<div id="container"></div>

// js 代码
const data = [
  { name: 'zxn', age: 18, sex: '男' },
  { name: 'zyh', age: 18, sex: '女' }
]

const mDom = document.getElementById('container')

for (let i = 0; i < data.length; i++) {
  mDom.innerHTML += `
  <p>${data[i].name}的基础信息</p>
  <ul>
    <li>姓名:${data[i].name}</li> // 这里如果使用了解构会更简单
    <li>年龄:${data[i].age}</li>
    <li>性别:${data[i].sex}</li>
  </ul>
`
}

最后

可以看到,从最初的 js 操作真实 DOM,到后来的数组拼接实现,至后来的 ES6 模板字符串,js 内书写元素的方式越来越便捷和符合我们的编写习惯。这里有所有的代码,可点击查看,注意在 origin 文件夹下。