这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
在初学vue的时候,我就一直在想为什么在<span> Message: {{ msg }} </span>
中使用{{}}就可以将msg替代为对应数据对象上 'msg' property 的值?它的底层原理又是什么?为什么需要这样的语法呢?毕竟vue官网上只简单的说了一句:使用“Mustache”语法 (双大括号) 的文本插值。所以我就去查了一下Mustache语法,才发现Mustache并不是vue的专属语法,它的出现比vue.js更早,也有其他的框架使用了Mustache语法
1.什么是模版引擎
JavaScript 模板引擎是在数据与界面分离的情况下将数据转变成视图的最优雅的解决方案(目前为止,如果有更好的在下面评论区提醒我一下?)
2.Mustache简介
Mustache翻译过来的中文意思是胡子,只是因为{{}} 看起来很像人的胡子(我都呆了?)。他是一种没有逻辑的模板语法,它只有标签没有逻辑处理(轻逻辑),包括像if else判断 或者for 循环之类也不会去做处理。因为它是基于javascript 实现的模板引擎,所以可以使用JavaScript的地方就可以使用Mustache模版引擎。包括web浏览器、服务器环境(node)。也有很多框架在使用Mustache(如vue.js),并对其进行封装优化(如vue.js中的v-for,在Mustache中是无法使用for循环的)
3.历史变革:将数据变为视图的方案
俗话说没有对比就没有伤害,既然我们说Mustache好,那么它究竟好在哪呢,我们与之前的方案做一下对比就知道了,我们来举个?,实现下面的效果
1.纯DOM法
试试用纯DOM法来写一次就深有体会了(代码很长,你忍一下)
<div id="container"></div>
<script>
const data = [{
title: '疾风剑豪简介',
name: '亚索',
address: '艾欧尼亚',
passive: '被动:浪客之道',
qSkill: '斩刚闪',
wSkill: '风之壁障',
eSkill: '踏前斩',
rSkill: '狂风绝息斩',
},{
title: '盲僧简介',
name: '李青',
address: '艾欧尼亚',
passive: '40%攻速加成',
qSkill: '天音波/回音击',
wSkill: '金钟罩/铁布衫',
eSkill: '天雷破/摧筋断骨',
rSkill: '中国足球',
}]
const container = document.getElementById('container')
const len = data.length
for (let i = 0; i < len; i++) {
const item = data[i]
const item1 = document.createElement('div')
item1.className = 'item_box'
const info1 = document.createElement('h1')
info1.innerText = item.title
const hName = document.createElement('h2')
hName.innerText = '姓名:'+item.name
const aName = document.createElement('h2')
aName.innerText = '地点:'+item.address
const ui1 = document.createElement('ui')
const qli1 = document.createElement('li')
qli1.innerText ='被动:'+item.passive
const qli2 = document.createElement('li')
qli2.innerHTML = 'q:'+item.qSkill
const qli3 = document.createElement('li')
qli3.innerText = 'w:'+item.wSkill
const qli4 = document.createElement('li')
qli4.innerText = 'e:'+item.eSkill
const qli5 = document.createElement('li')
qli5.innerText = 'r:'+item.rSkill
item1.appendChild(info1 )
item1.appendChild(hName )
item1.appendChild(aName )
ui1.appendChild(qli1)
ui1.appendChild(qli2)
ui1.appendChild(qli3)
ui1.appendChild(qli4)
ui1.appendChild(qli5)
item1.appendChild(ui1)
container.appendChild(item1)
}
</script>
我们可以看到,我们需要通过id 获取DOM节点,并在for循环创建与数据对应每一个节点,然后通过+
斩断连接数据,被创建的节点都是孤儿节点,我们还需要手动追加到父节点中。
2.数组join连接法
<script>
const container = document.getElementById('container')
const len = data.length
for (let i = 0; i < len; i++) {
const item = data[i];
container.innerHTML += [
'<div class="item_box">',
'<h1>'+item.title+'</h1>',
'<h2>姓名:'+item.name+'</h2>',
'<h2>地点:'+item.address+'</h2>',
'<ul>',
'<li>被动:'+item.passive+'</li>',
'<li>q:'+item.qSkill+'</li>',
'<li>w:'+item.wSkill+'</li>',
'<li>e:'+item.eSkill+'</li>',
'<li>r:'+item.rSkill+'</li>',
'</ul>',
'</div>',
].join('')
}
</script>
因为双引号是不能换行的,所以我们将每一行看成是数组中的每一项,然后通过join连接拼成一个字符串。并且在每一项中我们可以通过+
的方法斩段连接我们需要填充的内容。比纯的DOM方法简洁了不少
3.es6反引号法
在es6中新增了一个反引号,在反引号中是可以换行的所以我们就不需要先将其放入到数组中再转换成字符串来。并且新增了${}
语法糖我们也可以不用+
去斩断连接字符串了.
for (let i = 0; i < len; i++) {
const item = data[i]
container.innerHTML +=
`<div class="item_box">
<h1>${item.title}</h1>
<h2>姓名:${item.name}</h2>
<h2>地点:${item.address}</h2>
<ul>
<li>被动:${item.passive}</li>
<li>q:${item.qSkill}</li>
<li>w:${item.wSkill}</li>
<li>e:${item.eSkill}</li>
<li>r:${item.rSkill}</li>
</ul>
</div>`
}
4.我们来总结一下曾经出现过的将数据转变成视图的方法,可以看出来对于程序开发者来说,代码量在逐步减少:
1.纯DOM法需要创建节点并且追加到父节点上(性能最优,因为后面的数组join法或者反引号法解析完成之后还是需要进行DOM操作,但是对于开发者来说太过麻烦了,其性能差别也不是特别大,或者说不必要为了这一点性能而花费大量的时间去操作DOM)
2.因为innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML,而这个HTML必须是字符串类型。我们直接写的话,如果是比较复杂的结构我们必须写在一行中,这样无法看清结构也不利于开发,偏偏双引号中无法换行但是数组却可以,并且数组通过join方法可以转为字符串,这样就解决了双引号带来的的问题,字符串又可以通过+
连接,所以我们在循环中(上诉例子)拼接HTML字符串
图1:双引号中的换行我们可以看到很明显的错误提示:
图二:通过数组换行
3.es6新增的反引号可以换行,所以我们不需要通过数组转成字符串了,而且${}
可以替代+
斩断连接字符串
图三:反引号换行:
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!