手撕Vue-查找指令和模板

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

大致的思路是这样的:

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

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

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

buildTemplate(fragment) {
    let nodeList = [...fragment.childNodes];

    // 1.遍历所有的节点
    nodeList.forEach(node => {

    });
}

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

image-20231015103931327

// 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);
    }
}

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

image-20231015104503123

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

image-20231015104624387

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

image-20231015104809104

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

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

image-20231015104833637

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

posted @   BNTang  阅读(257)  评论(0编辑  收藏  举报
  1. 1 总会有人离开 王巨星
  2. 2 月亮 孟凡明
  3. 3 迟里乌布
  4. 4 我只能离开 颜人中
  5. 5 达尔文 蔡健雅
  6. 6 夜色滚烫 叶明净
  7. 7 你的星环 路飞文
  8. 8 不再说话 三块木头
  9. 9 黄昏 粥粥和小伙/粥粥
  10. 10 爱不单行 刘大拿
  11. 11 心动贩卖机 PIggy
  12. 12 别来无恙 苏星婕
  13. 13 我们的歌 刘大拿
  14. 14 一直很安静 王贰浪
  15. 15 去有风的地方 清音
  16. 16 雪 Distance Capper/罗言
  17. 17 坏女孩 徐良/小凌
  18. 18 乐园 沧桑Cang333/虎皮蛋/曲甲
  19. 19 Ayo(Explicit) Chris Brown/Tyga
  20. 20 我的美丽feat.海洋Bo 海洋Bo/高睿
  21. 21 世事可爱 粥粥和小伙/粥粥
  22. 22 我记得 赵雷
  23. 23 我想牵着你的手 许嵩
  24. 24 人们都不懂 刘诺然
  25. 25 寻一个你(电视剧《苍兰诀》温情主题曲) TTTTTeehom
  26. 26 子莫格尼 杉和
  27. 27 Cat Cafe Shoffy
  28. 28 风停了雨停了我们还拥抱着 Superluckyqi
  29. 29 寂寞沙洲冷 于潼
  30. 30 三国恋 王巨星
  31. 31 达尔文 林俊杰
  32. 32 有些 颜人中
  33. 33 小模样 张小只ya
  34. 34 是否 程响
  35. 35 楼顶上的小斑鸠 队长
  36. 36 笑场 薛之谦
  37. 37 还是分开 张叶蕾
  38. 38 修炼爱情 林俊杰
  39. 39 二零三 毛不易
  40. 40 雅俗共赏 许嵩
  41. 41 Serendipity 古瑞斯Graps/Zakiya晴子
  42. 42 就让这大雨全都落下·2023 刘大拿
  43. 43 老男孩 筷子兄弟
  44. 44 有何不可 许嵩
  45. 45 缓缓 杜宣达
  46. 46 好久不见 陈奕迅
  47. 47 爱的魔法(Cover 金莎) 封茗囧菌
  48. 48 在你的身边 盛哲
  49. 49 带我去找夜生活 告五人
  50. 50 假面舞会 很美味
  51. 51 STAY The Kid LAROI/Justin Bieber
  52. 52 我好想睡觉的 无敌西红柿
  53. 53 日不落(温柔版)
  54. 54 恋爱画板 锦零
  55. 55 7710 好乐无荒/尹露浠
  56. 56 给你呀(又名:for ya) 蒋小呢
  57. 57 Love Story Taylor Swift
  58. 58 Plain Jane(Remix 13z) 鱼幼微
  59. 59 晚风 7opy/BT07
  60. 60 拜托 孙晨
  61. 61 乌梅子酱 李荣浩
  62. 62 南半球与北海道 范倪Liu
  63. 63 星河万里 Rom邢锐
寻一个你(电视剧《苍兰诀》温情主题曲) - TTTTTeehom
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

Loading

点击右上角即可分享
微信分享提示