当前位置: 首页 > article >正文

手写MVVM框架-收集依赖

响应式数据完成之后我们需要根据数据进行动态更新dom,但是更新之前我们需要MVVM进行动态更新的时候,需要知道data里面的某一个属性,都哪些dom用到了,这样才能根据真实节点进行准确更新。

所以这一章我们来实现这个功能。

首先我们需要进行渲染之前的准备工作(收集依赖)

 收集的过程中,我们主要是对于文本节点(nodeType=3)的节点进行收集,如果是元素节点,则重新调用方法,如果是文本节点的话则获取模板(去掉{ {}})的名称,创建两个Map 一个通过VNode关联模板、一个通过模板关联VNode,这样如果某一个模板值发生改变就可以轻易的获取关联的节点从而修改dom

//创建render.js 位置在src/core/render.js

const vnodeToTemplate = new Map()
const templateToVNode = new Map()

/**
 * 预备渲染
 * @param {*} vm 
 * @param {*} vnode 
 * @returns 
 */
export function prepareRender(vm, vnode) {
    if(!vnode) return
    if(vnode.nodeType === 1) { // 元素节点
        vnode.children.forEach(childVNode => {
            prepareRender(vm, childVNode)
        })
    }
    if(vnode.nodeType === 3) { // 文本节点()
        analysisTemplateString(vnode)
    }
}

/**
 * 函数analysisTemplateString用于分析模板字符串
 * @param {*} vnode 
 */
function analysisTemplateString(vnode) {
    // 获取文本里面的模板
    const templateString = vnode.text.match(/{
  
  {[a-zA-Z0-9_.]+}}/g)
    if(templateString) {
        // 遍历获取到的模板
        templateString.forEach(template => {
            // 设置VNode到模板的映射关系
            setVnodeToTemplate(template, vnode)
            // 设置模板到VNode的映射关系
            setTemplateToVnode(template, vnode)
        })
    }
}

function setVnodeToTemplate(template, vnode) {
    template = getTemplateName(template)
    // 如果存在VNode
    if(vnodeToTemplate.has(vnode)) {
        vnodeToTemplate.get(vnode).push(template)
    } else { // 如果不存在VNode
        vnodeToTemplate.set(vnode, [template])
    }
}

function setTemplateToVnode(template, vnode) {
    template = getTemplateName(template)
    // 如果存在VNode
    if(templateToVNode.has(template)) {
        templateToVNode.get(template).push(vnode)
    } else { // 如果不存在VNode
        templateToVNode.set(template, [vnode])
    }
}

function getTemplateName(template) {
    return template.replace(/{
  
  {|}}/g, '');
}

export function getVnodeByTemplate() {
    return templateToVNode
}

export function getTemplateToVnode() {
    return vnodeToTemplate
}

然后我们在mount中调用该方法

 我们在浏览器上可以看到两个map都已经添加上依赖了

本章总结:

1.在上一节构建完虚拟dom后,通过传入虚拟dom来收集依赖

2.对虚拟dom进行分析,如果是元素节点则重新调用方法,如果是文本节点则进行分析

3.在分析的过程中获取文本节点的内容通过正则获取出来模板,然后把当前的依赖添加到map中(VNodeToTemplate以及TempalteToVNode)


http://www.kler.cn/a/532764.html

相关文章:

  • 【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR
  • LabVIEW微位移平台位移控制系统
  • Vue.js组件开发-实现图片浮动效果
  • 使用balenaEtcher导致U盘写保护
  • Vim的基础命令
  • 自定义数据集 使用scikit-learn中SVM的包实现SVM分类
  • 优选算法合集————双指针(专题二)
  • ZZNUOJ(C/C++)基础练习1051——1060(详解版)
  • linux 命令笔记
  • Linux(Centos)安装allnnlp失败,jsonnet报错
  • git进阶--4---git rebase 和 git merge的区别与联系
  • kubernetes 核心技术-Helm
  • MySQL 事务实现原理( 详解 )
  • 【web js逆向分析易盾滑块fp参数】逆向分析网易易盾滑块的 fp 参数,仅供学习交流
  • 渗透笔记2
  • 人工智能赋能企业系统架构设计:以ERP与CRM系统为例
  • 【零基础到精通】小白如何自学网络安全
  • 5 前端系统开发:Vue2、Vue3框架(上):Vue入门式开发和Ajax技术
  • 【大数据技术】案例03:用户行为日志分析(python+hadoop+mapreduce+yarn+hive)
  • 【医学影像 AI】EyeMoSt+:用于眼科疾病筛查的置信度感知多模态学习框架
  • 分享从零开始学习网络设备配置--任务6.5 实现园区网安全接入互联网
  • 网工_CSMA/CD协议
  • 【C语言深入探索】:指针高级应用与极致技巧(二)
  • C/C++炫酷烟花②(完整代码)
  • 5 前端系统开发:Vue2、Vue3框架(中):Vue前端工程化组件式开发
  • 跨域问题和解决方案