本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2024-11(8)

vue源码解析之mustache模板引擎

发布于2021-05-30 07:09     阅读(1068)     评论(0)     点赞(15)     收藏(5)


数据变为视图的方法

  1. 纯Dom方法:非常笨拙,没有实战价值
  2. 数据join法:曾今流行
  3. ES6反引号法:`${}`语法糖
  4. 模板引擎:解决数据变为视图最优雅的方法

Mustache基础用法 

  1. <script id="template" type="x-tmpl-mustache">
  2. <div>hello {{thing}}</div>
  3. </script>
  4. <script type="text/javascript">
  5. var template = $("#template").html();
  6. var r = Mustache.render(template,{
  7. thing:'world'
  8. })
  9. </script>

Mustache原理

什么是token,通过源码发现,token格式如下

模板字符串:

<h1>我买了一个{{thing}},好{{mood}}</h1>

对应的tokens:

  1. [
  2. ['text','<h1>我买了一个'],
  3. ['name','thing'],
  4. ['text',',好'],
  5. ['name','mood'],
  6. ['text','啊</h1>']
  7. ]

mustache实现原理

1.index.js入口文件

  1. import parseTemplateToTokens from './parseTemplateToTokens'
  2. import renderTemplate from './renderTemplate'
  3. let mustache = {
  4. render(templateStr,data){
  5. let tokens = parseTemplateToTokens(templateStr)
  6. var dom = renderTemplate(tokens,data)
  7. return dom
  8. }
  9. }
  10. export default mustache

2.parseTemplateToTokens.js解析html字符串为tokens

  1. import Scanner from './Scanner'
  2. import nestTokens from './nestTokens'
  3. export default function parseTemplateToTokens(templateStr){
  4. let scanner = new Scanner(templateStr)
  5. let words
  6. let tokens = []
  7. while (!scanner.eos()) {
  8. words = scanner.scanUtil('{{')
  9. words&&tokens.push(['text',words])
  10. scanner.scan('{{')
  11. words = scanner.scanUtil('}}')
  12. if(words){
  13. switch (words[0]) {
  14. case '#':
  15. tokens.push(['#',words.substring(1)])
  16. break;
  17. case '/':
  18. tokens.push(['/',words.substring(1)])
  19. break;
  20. default:
  21. tokens.push(['name',words])
  22. break;
  23. }
  24. }
  25. scanner.scan('}}')
  26. }
  27. return nestTokens(tokens)
  28. }

3.Scanner .js对html字符串进行扫描

  1. export default class Scanner {
  2. constructor(templateStr) {
  3. this.tail = this.templateStr = templateStr
  4. this.pos = 0
  5. }
  6. //过掉指定标签
  7. scan(tag){
  8. if(this.tail.indexOf(tag)===0){
  9. this.pos +=tag.length
  10. this.tail = this.templateStr.substring(this.pos)
  11. }
  12. }
  13. //查找到某个指定标签
  14. scanUtil(stopTag){
  15. let startPos = this.pos
  16. while (!this.eos()&&this.tail.indexOf(stopTag)!==0) {
  17. this.pos++
  18. this.tail = this.templateStr.substring(this.pos)
  19. }
  20. return this.templateStr.substring(startPos,this.pos)
  21. }
  22. //end of string
  23. eos(){
  24. return this.pos>=this.templateStr.length
  25. }
  26. }

4.nestTokens.js对tokens进行折叠,利用栈的思想以及引用类型的算法

  1. export default function nestTokens(tokens){
  2. let sections = []
  3. let nestTokens=[]
  4. let collector = nestTokens
  5. for(let i = 0;i<tokens.length; i++){
  6. let token = tokens[i]
  7. if(token[0]==='#'){
  8. //进栈
  9. sections.push(token)
  10. collector.push(token)
  11. collector = token[2] = []
  12. }else if(token[0]==='/'){
  13. //出栈
  14. sections.pop()
  15. collector = sections.length?sections[sections.length-1][2]:nestTokens
  16. }else{
  17. collector.push(token)
  18. }
  19. }
  20. return nestTokens
  21. }

5.renderTemplate.js结合数据渲染html字符串

  1. import lookup from './lookup'
  2. export default function renderTemplate(tokens,data){
  3. console.log(tokens,data)
  4. let templateStr = ''
  5. for(var i = 0;i<tokens.length;i++){
  6. let token = tokens[i]
  7. if(token[0]==='text'){
  8. templateStr+=token[1]
  9. }else if(token[0]==='name'){
  10. templateStr+=lookup(token[1],data)
  11. }else if(token[0]==='#'){
  12. //数据递归遍历
  13. var ary = lookup(token[1],data)
  14. for(var j = 0 ;j<ary.length;j++){
  15. templateStr+=renderTemplate(token[2],ary[j])
  16. }
  17. }
  18. }
  19. return templateStr
  20. }

6.lookup.js查找数据

  1. export default function lookup(keyNames,dataObj){
  2. let value = dataObj
  3. //例如a.b.c这种数据查找方法
  4. if(keyNames!=='.'){
  5. var keys = keyNames.split('.')
  6. for(let i = 0;i<keys.length;i++){
  7. var key = keys[i]
  8. value = value[key]
  9. }
  10. }
  11. return value
  12. }

 

 

原文链接:https://blog.csdn.net/qq_38761664/article/details/117364745




所属网站分类: 技术文章 > 博客

作者:哦八戒八戒

链接:http://www.qianduanheidong.com/blog/article/115814/34ed99a8fd41594a0249/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

15 0
收藏该文
已收藏

评论内容:(最多支持255个字符)