框架原理
- 虚拟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不行吗?
- data中有很多属性,有些被用到,有些可能不被用到
- 被用到的会走get,不被用到的不会走get
- 未走get的属性,我们set的时候也无需关心
- 避免不必要的重复渲染
- 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的异步
为何需要异步?
- 可能会执行多次setState
- 无法规定、限制用户如何使用setState
- 没必要每次setState都重新渲染,考虑性能
- 即使是每次重新渲染,用户也看不到
- 只看到最后的结果即可
- 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.热爱编程