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

手写MVVM框架-构建虚拟dom树

MVVM的核心之一就是虚拟dom树,我们这一章节就先构建一个虚拟dom树

首先我们需要创建一个VNode的类

// 当前类的位置是src/vnode/index.js 
export default class VNode{
    constructor(
        tag, // 标签名称(英文大写)
        ele, // 对应真实节点
        children, // 子节点
        text, // 文本内容
        data, // 节点数据
        parent, // 父节点
        nodeType, // 节点类型
        key // 节点key
    ) {
        this.tag = tag;
        this.ele = ele;
        this.children = children;
        this.text = text;
        this.data = data;
        this.parent = parent;
        this.nodeType = nodeType;
        this.key = key;
        this.env = {} // 环境变量
        this.instructions = [] // 指令
        this.template = [] // 当前节点的模板   
    }
}

第二步:构建虚拟dom

 构建虚拟dom树的操作我们放在mount事件里面,现在需要创建mount.js

import VNode from '../vnode/index'

/**
 * 给MiniVue添加挂载方法
 * @param {*} MiniVue 
 */
export function initMount(MiniVue) {
    MiniVue.prototype.$mount = function (el) {
        let root = document.getElementById(el)
        mount(this, root)
    }
}

/**
 * 实现mount事件
 * @param {*} vm 
 * @param {*} el 
 */
function mount(vm, el) {
    console.log('开始挂载')
    // 构建虚拟Dom
    vm._vnode = constructVnode(vm, el, parent)
    // 预备渲染
}

function constructVnode(vm, el, parent) {
    let vnode = null;
    const tag = el.nodeName
    const text = el.textContent.trim()
    const data = {}
    const nodeType = el.nodeType
    const key = ""
    vnode = new VNode(tag, el, [], text, data, parent, nodeType, key)
    // 递归构建子节点
    vnode.ele.childNodes.forEach(child => {
        const childNodes = constructVnode(vm, child, vnode)
        if(childNodes instanceof Array) {
            vnode.children.push(...childNodes)
        } else {
            vnode.children.push(childNodes)
        }
    })
    return vnode
}

/**
 * 获取节点的文本数据(文本节点)
 * @param {*} el 
 */
function getNodeText(el) {
    return el.nodeType === 3 ? el.textContent.trim() : ''
}

init方法里面执行当前mount

我们在浏览器里面可以看到当前构建的虚拟dom树

本章总结:

1.创建虚拟DOM的类

2.给原型添加mount方法,通过根节点el构建虚拟dom

3.构建dom时,使用深度优先搜索算法(反复调用本身方法),获取子节点


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

相关文章:

  • Chapter 6 -Fine-tuning for classification
  • Day33【AI思考】-分层递进式结构 对数学数系的 终极系统分类
  • 深入浅出并查集(不相交集合实现思路)
  • deepseek本地部署会遇到哪些坑
  • SpringMVC全局异常处理+拦截器使用+参数校验
  • java练习(5)
  • 在Vue3 + Vite 项目中使用 Tailwind CSS 4.0
  • 多线程创建方式三:实现Callable接口
  • WireShark4.4.2浏览器网络调试指南:偏好设置下(十)
  • SpringBoot+Mybatis整合Mysql数据库的Demo
  • 《黑马点评》实战笔记
  • Qwen2.5-Max:AI技术的新里程碑
  • 力扣 55. 跳跃游戏
  • 【OS】AUTOSAR架构下的Interrupt详解(下篇)
  • Verilog基础(五):时序逻辑
  • 【贪心算法篇】:“贪心”之旅--算法练习题中的智慧与策略(三)
  • 【C++】B2124 判断字符串是否为回文
  • 50【Windows与Linux】
  • 【C++】string类(上):string类的常用接口介绍
  • 与,|与||的区别
  • python leetcode 笔记
  • 一些硬件知识【20250/2/3】
  • html中的表格属性以及合并操作
  • DeepSeek-R1-Distill-Qwen-1.5B 本地部署报错解决
  • MySQL(InnoDB统计信息)
  • Unix 进程的启动方式及经典和现代做法(中英双语)