首页 > 其他分享 >手撕Vue-编译模板数据

手撕Vue-编译模板数据

时间:2023-10-15 18:23:18浏览次数:32  
标签:Vue name age args value 编译 模板

经上一篇编译指令数据后,我们已经可以将指令数据编译成具体需要展示的数据了,上一篇只是编译了指令数据,还没有编译模板数据,这一篇我们就来编译模板数据。

也就是 {{}} 这种模板的形式我们该如何编译,其实和指令数据编译的思路是一样的,废话不多说,直接上代码。

改造一下 buildText 方法,让它支持编译模板数据,调用 CompilerUtil content 方法,传入模板数据,返回编译后的数据,然后再将编译后的数据替换到文本节点中。

CompilerUtil['content'](node, content, this.vm);

在 CompilerUtil 中添加 content 方法,该方法和指令数据编译的思路是一样的,只是编译的数据不一样,指令数据是 v-text 这种,而模板数据是 {{}} 这种。

/**
 * 处理模板字符串
 * @param node 当前元素
 * @param value 指令的值
 * @param vm Nue 的实例对象
 */
content: function (node, value, vm) {
    // console.log(value); // {{ name }} -> name -> $data[name]
    node.textContent = this.getContent(vm, value);
}

getContent 方法我单独拿出来,我先贴代码,然后再解释。

/**
 * 获取指定模板字符串的内容
 * @param vm Nue 的实例对象
 * @param value 指令的值
 */
getContent(vm, value) {
    const reg = /\{\{(.+?)\}\}/gi;
    return value.replace(reg, (...args) => {
        // 第一次执行 args[1] = name
        // 第二次执行 args[1] = age
        return this.getValue(vm, args[1]);
    });
},

getContent 方法中,我们先定义了一个正则表达式,用来匹配模板字符串,/\{\{(.+?)\}\}/gi 这个正则表达式的意思是匹配 {{}} 里面的内容,g 表示全局匹配,i 表示忽略大小写,(.+?) 表示匹配任意字符,+ 表示匹配一次或多次,? 表示非贪婪模式,也就是匹配到第一个 }} 就结束匹配。() 表示分组,args[1] 就是分组匹配到的内容。

在方法当中,我们调用了 getValue 方法,该方法的作用是获取模板字符串的值,在运行测试代码的时候,我发现, {{ name }} 这种模板编译出来是 undefined 所以我们需要在 getValue [obj][key] 的时候,去一下空格:

return data[currentKey.trim()];

这样就可以了,我们再来看一下测试代码:

<p>{{ name }}</p>
<p>{{age}}</p>
<p>{{time.h}}</p>
<p>{{name}}-{{age}}</p>

发现 {{name}}-{{age}} 这种也可以编译了,那么可以我们来看看我们 getContent 源码的执行效果,如果是 {{name}}-{{age}}, value 等于 {{name}}-{{age}} 进入 replace 循环,第一次执行 args[1] 等于 name,第二次执行 args[1] 等于 age,第一次循环已经将我们的 {{name}}-{{age}} 替换为了 BNTang-{{age}},第二次循环将 {{age}} 替换为了 age,所以最终的结果就是 BNTang-33

标签:Vue,name,age,args,value,编译,模板
From: https://www.cnblogs.com/BNTang/p/17765937.html

相关文章

  • 手撕Vue-编译指令数据
    经过上一篇的分析,完成了查找指令和模板的功能,接下来就是编译指令的数据了。所以本章节主要处理的方法则是buildElement方法,我们先分析一下我们所拿到的数据在进行编码,这样会更加清晰一些。我将name,value打印出来,分别对应的值是name:v-model,value:name,在今后我们的命......
  • 二分模板
    整数二分边界boolcheck(intx){/*...*/}//检查x是否满足某种性质//区间[l,r]被划分成[l,mid]和[mid+1,r]时使用:intbsearch_1(intl,intr){while(l<r){intmid=l+r>>1;if(check(mid))r=mid;//check()判断mid是......
  • 小程序底层技术机制解读 - 模板引擎
    模板引擎在小程序开发中扮演着关键的角色,它负责将数据渲染到页面上,实现动态的用户界面。本文将深入解读小程序的模板引擎的底层技术机制,以及如何使用它来实现数据和界面的绑定。同时,我们将提供一个简单的代码演示,以帮助读者更好地理解模板引擎的实际应用。小程序模板引擎的作用小程......
  • vue学习六
    <divid="app6"><divv-for="iteminlist">{{item}}</div></div><script>constapp6=newVue({el:'#app6',data:{list:["1&qu......
  • vue学习五
    <divid="app5"><button@click="exchange(-5)">点我减五</button><button@click="exchange(5)">点我加五</button></div><script>constapp5=newVue({......
  • [Vue]初始Vue
    Vue2,建议新人直接饮用vue.js文件 <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><metahttp-equiv=......
  • Error: Vue packages version mismatch: - [email protected] (D:\前端\vue01\node_module
    Error:Vuepackagesversionmismatch:[email protected](D:\\前端\vue01\node_modules\vue\dist\vue.runtime.common.js)[email protected](D:\前端\vue01\node_modules\vue-template-compiler\package.json)根据提示信息,是版本不匹配的问题,可以直接找到vu......
  • vue js获取当天日期
    <template><div><p>Todayis{{today}}</p></div></template><script>exportdefault{data(){return{today:''}},mounted(){this.today=this.getCurrentDate();......
  • 输入vue ui出现Failed to get response from /vue-cli-version-marker
      解决办法:找到 .vuerc文件,位置在C:\Users\当前用户.vuerc将packageManager修改如下:原因是本地hadoop环境变量回合vue项目有冲突,他们都要用到yarn集群 修改后再重新输入vueui,没有报错信息且自动打开Vue项目管理器的页面  ......
  • 一个vuepress配置问题,引发的js递归算法思考
    前言这两天在尝试用语雀+vuepress+github搭建个人博客。小破站地址:王天的web进阶之路语雀作为编辑器,发布文档推送github,再自动打包部署,大概流程如下。问题我使用的elog插件批量导出语雀文档。elog采用的配置是所有文章平铺导出,没有按照语雀知识库目录生成markdown,这导......