接着上一篇文章,我们已经实现了提取元素到内存的过程,接下来我们要实现的是查找指令和模板。

大致的思路是这样的:

  1. 遍历所有的节点
  2. 需要判断当前遍历到的节点是一个元素还是一个文本
  3. 如果是一个元素, 我们需要判断有没有v-model属性
  4. 如果是一个文本, 我们需要判断有没有{{}}的内容

那么随着思路的展开,接下来我们就来实现这个功能。

首先我们编写一个 buildTemplate 方法,主要功能是利用指定的数据编译内存中的元素:

buildTemplate(fragment) {
let nodeList = [...fragment.childNodes]; // 1.遍历所有的节点
nodeList.forEach(node => { });
}

buildTemplate 方法定义在 Compiler 类中,我们需要在 compile 方法中调用它:

// 2.利用指定的数据编译内存中的元素
this.buildTemplate(fragment);

然后我们在 buildTemplate 方法中完善我们的代码,这里我就先直接上完整的实现代码:

buildTemplate(fragment) {
let nodeList = [...fragment.childNodes]; // 1.遍历所有的节点
nodeList.forEach(node => {
// 2.需要判断当前遍历到的节点是一个元素还是一个文本
if (this.vm.isElement(node)) {
// 是一个元素
this.buildElement(node);
} else {
// 不是一个元素
this.buildText(node);
}
});
} buildElement(node) {
// 可以通过 node.attributes 获取到当前元素上所有的属性
let attrs = [...node.attributes]; // 1.遍历所有的属性
attrs.forEach(attr => {
let {name, value} = attr;
if (name.startsWith('v-')) {
console.log('是Vue的指令, 需要我们处理', name);
}
});
} buildText(node) {
// 可以通过 node.textContent 获取到当前文本节点的内容
let content = node.textContent; // 编写一个正则表达式, 用来匹配 {{}}
// 如下正则表达式的含义是: 匹配 {{}} 中间的内容
// /: 正则表达式通常以斜杠 / 开始和结束,表示正则表达式的开始和结束。
// \{ 和 \}: 这些是转义字符,用于匹配实际的花括号 { 和 }。花括号在正则表达式中具有特殊意义,因此需要使用反斜杠进行转义。
// \{\{ 和 \}\}: 这是正则表达式的起始和结束部分,用于匹配双花括号 {{ 和 }}。
// .+?: 这部分用于匹配双花括号内的任意字符,. 表示匹配任意字符,+ 表示匹配一个或多个前面的字符,? 表示非贪婪匹配,即尽可能匹配最短的内容。这样确保匹配到最近的结束双花括号 }}。
// /g: g 是正则表达式的标志,表示全局匹配,即匹配字符串中的所有符合条件的部分。
// /i: i 也是正则表达式的标志,表示不区分大小写匹配,这意味着 {{...}} 和 {{...}} 都会被匹配到。
// 因此,这个正则表达式可以用于在字符串中找到并提取所有的 {{...}} 结构,不区分大小写,不贪婪匹配,且匹配所有出现的情况。
let reg = /\{\{.+?\}\}/gi;
if (reg.test(content)) {
console.log('是一个文本节点, 需要我们处理', content);
}
}

好了,我们来看一下效果,我们在浏览器中打开,然后打开控制台,可以看到如下的效果:

发现,只有 v-model 指令被处理, {{}} 没有被处理,如下图我框出了 <p>

也就是说我们循环节点的时候,只循环了一层,没有循环到 <p> 标签中的文本节点,所以我们需要修改一下 buildTemplate 方法, 让它支持递归,处理子元素(处理后代):

// 处理子元素(处理后代)
this.buildTemplate(node);

改造后,我们再来看一下效果,可以看到 {{}} 也被处理了:

好了,到这里我们就实现了查找指令和模板的功能,下一篇我们来继续完善一下我们的不完整的代码,一步一步来慢慢撕。

手撕Vue-查找指令和模板的更多相关文章

  1. Vue自定义指令使用场景

    当你第一次接触vue的时候,一定会使用到其中的几个指令,比如:v-if.v-for.v-bind...这些都是vue为我们写好的,用起来相当的爽.如果有些场景不满足,需要我们自己去自定义,那要怎么办呢 ...

  2. 编译原理--05 用C++手撕PL/0

    前言 目录 01 文法和语言.词法分析复习 02 自顶向下.自底向上的LR分析复习 03 语法制导翻译和中间代码生成复习 04 符号表.运行时存储组织和代码优化复习 05 用C++手撕PL/0 在之前 ...

  3. 剖析手写Vue,你也可以手写一个MVVM框架

    剖析手写Vue,你也可以手写一个MVVM框架# 邮箱:563995050@qq.com github: https://github.com/xiaoqiuxiong 作者:肖秋雄(eddy) 温馨提 ...

  4. vue的指令

    我之前学了学angular 发现angular和vue的指令有点类似 先说一下 new  Vue({          el: "#box", // element(元素) 当前作 ...

  5. vue自定义指令用法总结及案例

    1.vue中的指令有哪些?

  6. 第3章-Vue.js 指令扩展 和 todoList练习

    一.学习目标 了解Vue.js指令的实现原理 理解v-model指令的高级用法 能够使用Vue.js 指令完成 todoList 练习(重点+难点) 二.todoList练习效果展示 2.1.效果图展 ...

  7. vue自定义指令clickoutside使用以及扩展用法

    vue自定义指令clickoutside使用以及扩展用法 产品使用vue+element作为前端框架.在功能开发过程中,难免遇到使用element的组件没办法满足特殊的业务需要,需要对其进行定制,例如 ...

  8. vue自定义指令clickoutside扩展--多个元素的并集作为inside

    都是个人理解,如果发现错误,恳请大家批评指正,谢谢.还有我说的会比较啰嗦,因为是以自身菜鸡水平的视角来记录学习理解的过程,见谅. 1.前言 产品使用vue+element作为前端框架.在功能开发过程中 ...

  9. 每个人都能实现的vue自定义指令

    前文 先来bb一堆废话哈哈.. 用vue做项目也有一年多了.除了用别人的插件之外.自己也没尝试去封装指令插件之类的东西来用. 刚好最近在项目中遇到一个问题.(快速点击按钮多次触发多次绑定的方法),于是 ...

  10. Vue的指令以及组件化开发

    一. 自定义指令 如何: 1. 创建指令 Vue.directive("指令名",{ inserted(elem){//指令所在的元素被加载到DOM树上后自动执行指令 //elem ...

随机推荐

  1. springboot自定义消息转换器

    import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; im ...

  2. MODBUS-TCP转Ethernet IP 网关连接空压机配置案例

    本案例是工业现场应用捷米特JM-EIP-TCP的Ethernet/IP转Modbus-TCP网关连接欧姆龙PLC与空压机的配置案例.使用设备:欧姆龙PLC,捷米特JM-EIP-TCP网关, ETHER ...

  3. [ESP] 使用Ayla API Reference配网和连Ayla云

    示例用的文档及链接 US Dev Dashboard(查看oem-id和oem-key) https://dashboard-dev.aylanetworks.com/ Ayla API Refere ...

  4. 【IDEA】 远程调试

    远程调试 使用特定JVM参数运行服务端代码 要让远程服务器运行的代码支持远程调试,则启动的时候必须加上特定的JVM参数,这些参数是: -Xdebug -Xrunjdwp:transport=dt_so ...

  5. 【Kubernetes】yaml文件编写 -- 持续更新

    K8S通过yaml格式的声明式API与资源对象交互 API版本由apiVersion字段指定,API对象类型由kind字段指定 除此之外,每个API对象有三大类属性: metadata:元数据 spe ...

  6. 即构SDK10月迭代:新增多款语音音效、外部采集码流控制及Android SDK 最低支持操作系统版本调整

    即构SDK10月迭代内容来喽~~~ 本月调整了Android SDK 最低支持的操作系统版本,新增了流删除回调原因, 4种变音效果和外部采集码流控制,同时还对登录房间.媒体播放器以及第三方库进行了优化 ...

  7. win10安装mysql时提示错误:mysqld: Can't change dir to 'C: oftware\mysql\data\' (Errcode: 2 - No such file or directory)

    win10安装解压版mysql时,提示错误: 2019-10-22 09:02:00 2004 [ERROR] Can't find messagefile 'C:\WINDOWS\system32\ ...

  8. ubuntu 终端选中黏贴、自带截图

    鼠标选中 -- 复制 鼠标中键 -- 粘贴 注意,在tmux中,这个操作需要加上 Shift 键. PrtSc:截图整个桌面保存到Pictures Ctrl + PrtSc:截图整个桌面到剪贴板 Sh ...

  9. GPT-4助力数据分析:提升效率与洞察力的未来关键技术

    摘要 随着大数据时代的到来,数据分析已经成为企业和组织的核心竞争力.然而,传统的数据分析方法往往无法满足日益增长的数据分析需求的数量和复杂性.在这种背景下,ChatGPT-4作为一种先进的自然语言处理 ...

  10. 2023HWS_RE复现

    2023HWS_RE复现 参考wp:https://oacia.cc/hws-2023/ Android 参考这篇文章:https://www.52pojie.cn/thread-1680984-1- ...