前端框架原理

本文深入剖析前端框架原理,围绕Vue和React展开。介绍了vdom的概念、应用及diff算法,以减少DOM操作提高效率;阐述MVVM模式,包括数据与视图分离、响应式实现和模板解析;探讨组件化,涉及组件封装复用、JSX语法及与vdom关系;还比较了React和Vue的异同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

框架原理

  • 虚拟DOM
  • vue
  • React
  • 对比

1.vdom

vdom使vue和react的核心,先讲哪个都绕不开它

vdom比较独立,使用也比较简单

vdom是什么?为何会存在vdom?

  • virtual dom,虚拟DOM
  • DOM的操作非常昂贵,JS的运行效率高
  • 尽量减少DOM的操作,而不是推倒重来
  • 用JS模拟DOM结构
  • DOM的变化的对比,放在JS层来做(图灵完备语言),提高效率
  • 提高重绘性能

浏览器最耗费性能的是DOM操作,JS循环1万次都比不过DOM操作的耗费

 一个需求场景:

 

遇到的问题:

  • DOM操作时昂贵的,JS运行效率高
  • 尽量减少DOM操作,而不是推倒重来
  • 项目越复杂,影响就越严重
  • vdom可解决这个问题 

vdom如何应用,核心API是什么

  • h("标签名",{...属性...},[...子元素...])
  • h("标签名",{...属性...},"...")
  • patch(container,vnode)
  • patch(vnode,newVnode)

解答:

如何使用?可使用snabbdom的用法来举例

核心API:h函数、patch函数

介绍snabbdom(vdom的库)

 重做之间的demo

 

 

介绍一下diff算法

  • 什么是diff算法

  • 去繁就简

  • vdom为何用diff算法

DOM操作是昂贵的,因此尽量减少DOM操作

找出本次DOM必须更新的节点来更新,其他的不更新

这个找出的过程,就需要diff算法

  • diff算法的实现流程

patch(container,vnode);

patch(vnode,newVnode);

核心逻辑:createElement和updateChildren

 

 

2.MVVM

使用jQuery和vue或react的区别

  • 数据和视图的分离
  • 数据驱动视图

数据和视图的分离------>开放封闭原则

jQuery的数据和视图时在一起的,没有分离,新增li是通过js动态创建出来的

jQuery没有数据驱动视图,而是通过document.body.appendChld(node)直接操作DOM的

vue中数据和视图是分离的

vue中是数据驱动视图的,没有直接DOM操作

jQuery实现todo-list

vue实现todo-list

如何理解MVVM

MVC

 

MVVM 

  • Model模型、数据
  • View视图、模板(视图和模型是分离的)
  • ViewModel 连接Model和View

MVVM不算是一种创新,但其中的ViewModel却是一种创新

 

 如何实现MVVM?

  • vue框架的三大要素

修改数据后视图发生改变,怎么实现的?

模板如何解析(一些指令如v-for v-bind v-model)?

如何把模板和数据解析成DOM

三大要素:

响应式

vue如何监听到data的每个属性变化?

模板引擎

vue的模板如何被解析,指令如何处理?

渲染

vue的模板如何被渲染成html?以及渲染过程?

vue如何实现响应式

什么是响应式

  • 修改data属性之后,vue立即监听到

  • data属性被代理到vm(this)上

Object.definedProperty(ES5的 )

 

 

模拟

模拟监听data属性和属性绑定到vue实例上

vue如何解析模板

模板是什么

  • 本质:字符串
  • 有逻辑,如 v-if v-for 等
  • 与 html 格式很像,但有很大区别
  • 最终还要转换为 html 来显示
  • 模板最终必须转换成JS代码,

因为:

  • 有逻辑(v-if v-for ),必须用JS才能实现(图灵完备)

  • 转换为 html 渲染页面,必须用JS才能实现

  • 因此,模板最重要转换成一个JS函数(render函数)

render函数

  • with函数

  • render函数

模板中所有信息都包含在了render函数中

this即vm

price即this.price即vm.price,即data中的price

c即this.c即vm._c

 

从哪里可以看到render函数?

复杂一点的例子。render函数是什么样子的?

v-if v-for v-on都是怎么处理的

 

 

with(this){  // this 就是 vm
            return _c(
                'div',
                {
                    attrs:{"id":"app"}
                },
                [
                    _c(
                        'div',
                        [
                            _c(
                                'input',
                                {
                                    directives:[
                                        {
                                            name:"model",
                                            rawName:"v-model",
                                            value:(title),
                                            expression:"title"
                                        }
                                    ],
                                    domProps:{
                                        "value":(title)
                                    },
                                    on:{
                                        "input":function($event){
                                            if($event.target.composing)return;
                                            title=$event.target.value
                                        }
                                    }
                                }
                            ),
                            _v(" "),
                            _c(
                                'button',
                                {
                                    on:{
                                        "click":add
                                    }
                                },
                                [_v("submit")]
                            )
                        ]
                    ),
                    _v(" "),
                    _c('div',
                        [
                            _c(
                                'ul',
                                _l((list),function(item){return _c('li',[_v(_s(item))])})
                            )
                        ]
                    )
                ]
            )
        }

 

 

vue的实现流程

  • 解析模板成render'函数

模板中的所有信息都被render'函数包含

模板中用到的data中的属性,都变成了JS变量

模板中的v-model、v-for、v-on都变成了JS逻辑

render函数返回vnode

  • 响应式开始监听

​​​​​​​Object.definedProperty(vm,key,{set:function(){},get:function(){}})

将data属性代理到vue实例上

​​​​​​​

  • 首次渲染,显示页面,且绑定依赖

​​​​​​​初次渲染,执行updateComponent,执行vm._render()

执行render函数,会访问到vm.list和vm.title

会被响应式的get方法监听到

执行updateComponent,会走vdom的patch方法

patch将vnode渲染成DOM,初次渲染完成

为何要监听get,直接监听set不行吗?

  1. ​​​​​​​data中有很多属性,有些被用到,有些可能不被用到
  2. 被用到的会走get,不被用到的不会走get
  3. 未走get的属性,我们set的时候也无需关心
  4. 避免不必要的重复渲染

  • data属性变化,触发rerender ​​​​​​​

​​​​​​​修改属性,被响应式的set监听到

set中执行updateComponent

updateComponent重新执行vm._render()

生成的vnode和newVnode,通过patch进行对比

渲染到html中

​​​​​​​

3.组件化

对组件化的理解

组件的封装:封装视图、封装数据、封装变化逻辑

组件的复用:props传递、复用

​​​​​​​组件的封装

  • 视图的封装
  • 数据的封装
  • 变化逻辑的封装(数据驱动视图变化)

​​​​​​​

组件的复用

  • props传递
  • 复用

​​​​​​​

 

JSX是什么

JSX语法

  • html形式

  • 引入JS变量和表达式({})

  • if...else...

  • 循环

  • style和className

  • 事件

 

JSX解析成JS

JSX其实是语法糖

开发环境会将JSX编译成JS代码

JSX的写法大大降低了学习成本的编码工作量

JSX也会增加debug成本

  • JSX语法根本无法被浏览器所解析
  • 它如何在浏览器运行?

React.createElement("div",{id:"div1"},child1,child2,child3);

React.createElement("div",{id:"div1"},[child1,child2,child3]);

​​​​​​​

 

独立的标准

 

 

JSX和vdom是什么关系

为何需要dom

React.createElement和h

何时patch

  • 初次渲染-ReactDOM.render(<App/>,container);<App/>是jsx语法,经过React.createElement("div",null,[...])处理后,返回vnode
  • 会触发patch(container,vnode)

​​​​​​​

  • re-render ----->setState
  • 会触发patch(vnode,newVnode)

​​​​​​​

自定义组件的解析

根据props初始化实例,然后执行实例的render函数

render函数返回的还是vnode对象

  • div----->直接渲染<div>即可,vdom可以做到
  • Input和List,是自定义组件(class),vdom默认不认识
  • 因此Input和List定义的时候必须声明render函数

​​​​​​​

 

示例:

 

简述React和setState

  • setState的异步

为何需要异步?

  1. 可能会执行多次setState
  2. 无法规定、限制用户如何使用setState
  3. 没必要每次setState都重新渲染,考虑性能
  4. 即使是每次重新渲染,用户也看不到
  5. 只看到最后的结果即可

  • vue修改属性也是异步

 vue中第四步:data属性变化,触发rerender

修改属性,被响应式的set监听到,set执行会触发updateComponent,updateComponent是异步的,updateComponent重新执行vm._render(),生成的vnode和preVnode,通过patch进行对比,渲染到html中

  • setState的过程

每个实例对象,都有renderComponent方法,这个方法是继承过来的

执行renderComponent会重新执行实例的render方法

render函数返回newVnode,然后拿到preVnode

执行patch(preVnode,vnode)

比较React和vue

两者本质区别

模板和组件化的区别

  • 模板区别

​​​​​​​vue使用模板、React使用JSX,模板语法上,我更倾向于JSX,模板分离上,我更倾向于vue

  • 组件化区别

​​​​​​​React本身就是组件化,没有组件化就不是React,vue也支持组件化,不过是在MVVM上的扩展,对组件化,我更倾向于React,做的彻底而清晰

  • 两者共同点

​​​​​​​都支持组件化、都是数据驱动视图的

4.混合开发

 

5.热爱编程

 

6.其他

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值