• 【vue 原理相关】


    组件化和 MVVM

    组件化:

    很早以前就有 组件化 的概念,比如 asp, jsp, php。node也有类似的组件化,但是传统组件化,只是做分模块做静态渲染,更新数据时需要操作 DOM 节点,也就是 jQuery 比较流行时,vue 和 react 在 此基础上增加了创新,即为 数据驱动视图,通过 MVVM 原理实现。

    数据驱动视图:

    V-view
    VM-viewModel
    M-model

    view:代表 template 模板中的内容
    model: 代表 vue中的data,react中的 state。
    viewModel: 泛指view和model的连接层,通过监听事件和指令修改model中的数据

    响应式原理

    通过核心api Object.defineproperty 监听属性变化
    通过 Vue.set 和 Vue.delete 监听对象属性的增加和删除
    通过 重写数组原型 监听数组

    1. updateView - 更新视图
    2. 重写数组原型
    const oldArrayProperty = Array.prototype;
    const arrProto = Object.create(oldArrayProperty);
    [...数组原型的基础方法].forEach(methodName => {
    	arrProto[methodName] = function() {
    		updateView() // 更新视图
    		oldArrayProperty[methodName].call(this, ...arguments)
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 核心API -> 深度监听 -> 核心API 监听
    function defineReactive(target, key value){
    	observe(value) // 多层对象深度监听,一次性递归到底
    	Object.defineProperty(target, key {
    		get(){
    			return value
    		},
    		set(newValue){
    			if(newValue !== value){
    				observe(newValue) // 对象类型监听,如果从 直接变量 修改为 对象则需要深度监听
    				value = newValue
    				updateView() // 更新视图
    			}
    		}
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 递归深度监听
    function observe(target){
    	if(typeof target !== 'object' || target === null) return target;
    	if(Aray.isArray{target}){
    		target.__proto__ = arrProto
    	}
    	for(let key in target){
    		defineReactive(target, key , target[key])
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. model
    const data = {
    	name: '张三'
    }
    // 开启响应式监听
    observe(data) 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    vdom 和 diff 算法

    vdom

    总所周知,DOM 操作比较费时,一般都是通过jQuery操作DOM,但 vue 和 react 都是数据驱动视图,有效的通过 vdom 优化DOM 操作;
    所以vdom可以说是 用 JS 模拟 dom 结构,计算出最小的变更,再去操作 DOM

    diff 算法

    首先 vue 把树 diff 的时间复杂度O(n^3) , 优化到 O(n);
    根据统一层级对比,不做跨级比较;
    elem 不相同,则删掉重建,不再做深度比较;
    elem 和 key 两者都相同,则认为是相同节点,通过 patchVnode 做比较
    patchVnode 通过对比 oldVnnode 和 newVnode做比较,对应判断是应该做 add 还是 remove操作
    最终节点和key都相同并且都有chillren 的节点 通过 update Children 做对比,最终返回最新的vnode渲染到 DOM 节点中。

    模板编译

    了解模板编译之前需要先了解一下开发中不常用到的 with 语法;在此不赘述。
    通过 vue-template-complier 将模板解析为 render 函数,render 通过 with 语法返回一个 vnode 节点

    组件渲染和更新过程

    渲染-解析 template 模板为render 函数,触发监听 model 的 getter 和 setter;
    执行render 函数,生成 vnode 节点。通过 patch 函数,挂在到 对应的包裹容器中
    更行-当 model 中值被改变的时候,会触发 getter 中 已经观察者模式中的数据,触发 setter。
    重新执行 render 函数,生成 newVnode ,通过 patch 函数中的oldVnode,newVnode 对比(diff),得出最小差值的新节点后更新视图

    touch
    getter
    re-render
    setter
    render
    Component-render-function
    data-getter-setter
    Watcher
    vdom

    异步渲染

    首先 $nextTick 是在新增或者删除完节点之后立即可以获得元素的真实内容和节点长度时使用。
    多次 setData 的时候会汇总 data 设置,一次性更新视图,减少 DOM 操作次数,提高性能。

    随手记录,望指正。

  • 相关阅读:
    Deep Recurrent Q-Learning for Partially Observable MDPs(DRQN)
    el-dialog窗口添加滚动条
    数据结构--单链表
    计算机毕业设计ssm高校学科竞赛管理系统eolh8系统+程序+源码+lw+远程部署
    ElasticSearch(六)【分词器】
    SpringCloud源码分析 (Eureka-Server-入口分析和处理Client状态请求) (五)
    gdb调试
    Tmux 使用教程
    腾讯云4核8G服务器性能如何多少钱一年?
    lenovo联想笔记本ThinkPad系列T15p或P15v Gen3(21DA,21DB,21D8,21D9)原厂Win11系统镜像
  • 原文地址:https://blog.csdn.net/Mike_chen2stockings/article/details/126700089