虚拟DOM 组件化开发 原生JS的框架 (ES6+原生javascript)
优点
- 极速的渲染能力 虚拟DOM virtual DOM
- 高度组件化 组件之间高度复用
- 经历大量的测试 有一定的稳定性
虚拟DOM virtual DOM
虚拟DOM 就是在 真实DOM的基础上建立的一个抽象层 (把存储在javascripts 内存中DOM节点的数据 叫做 虚拟DOM)
我们对数据和状态所做的任何改动,都会被自动且高效的同步到虚拟DOM,最后再批量同步到DOM中
react 遵循 MIT 协议 开源框架
diff 算法
React会在内存中维护一个虚拟DOM树,当我们对这个树进行读或写的时候,实际上是对虚拟DOM进行的。当数据变化时,然后React会自动更新虚拟DOM,然后拿新的虚拟DOM和旧的虚拟DOM进行对比,找到有变更的部分,得出一个Patch,然后将这个Patch放到一个队列里,最终批量更新这些Patch到DOM中。
react 和 vue 对比
相同
a. react 和 vue 都有组件化思想 都有虚拟DOM DIff 算法
b. react 和 vue 都提供了组件化视图 (compoisible) 响应式数据概念
c. react 和 vue 都有核心渲染组件的API (Vue.component/React.Component) 都有 路由的概念 相同的路由机制 完整对应的组件生命周期 各自成熟的生态圈
不同
a. react 通过 javascript xml 来编写组件 vue 通过 template 模板来嵌套组件
b. vue 比 react 有更快的渲染速度 react比较vue相对复杂的框架 react 适用用业务逻辑超级变态的项目
c. 数据传递方式不一样 生命周期不一样 渲染模板不一样 {react} {{vue}}
d. vue 有指令 react 没有 指令 react 不能自定义指令 不能自定义过滤器
特点
1.虚拟dom (开发时候不需要在页面中写任何dom元素) victure dom
2.jsx语法(写页面时候使用javascript xml格式的语法)
3.组件化开发(react最核心的思想是将页面中任何一个区域或者元素都
看成是一个组件 Component)
4.单向数据流(组件和后端之间的数据是单向的,从后端流动到react组件中)
5.组件生命周期(任何一个组件在dom中都具有一个完整的声明周期,组件初始化的时候开始,组件被移除的时候消失,从而保证性能的优越)
-
react.min.js react
react-dom.min.js react-dom
browser.min.js javascript/XML
2.
react.min.js react 核心文件 包含了react diff 算法 虚拟DOM 模型 react事件机制
提供创建组件的API createClass Componentreact-dom.min.js 封装了操作react 组件API 负责把虚拟DOM 渲染 render 成真实DOM
ReactDOM.render()browser.min.js 负责解析 jsx 代码 , js内的html代码解析出来返回给浏览器
-
type=“text/babel” 允许js 里面 书写 html 代码 (jsx)
-
ReactDOM.render(虚拟DOM,真实DOM)
ReactDOM.render(,app);
React.createElement() 创建虚拟DOM -
data-reactroot 表面当前元素是 该组件的顶层标签
任何组件都只能有一个顶层标签 -
jsx 语法规则
遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;
遇到代码块(以 { 开头),就用 JavaScript 规则解析 -
注释 组件内部注释
{ /*{txt}
*/ }
创建组件 component
组件即将一段或几段完成各自功能的代码段封装为一个或几个独立的部分
每个组件 能完成独立的功能的,都是独立的部分
a. React.createClass 老版本 ES5 废弃
b. Reac.Component 新版本 ES6 class 类 extends 继承 React.Component 父类
c. 无状态组件 stateLess component 函数式组件组件名首字母必须大写 任何组件都只有一个顶层标签
render 组件生命周期钩子函数 把虚拟DOM 读取出JS内存 然后等待渲染成真实DOM
生命周期阶段 mount(载入) update(更新) unmount(销毁)
自定义函数 handleClick onClick={this.handleClick}
数据传递载体 组件通信 props(属性) state(状态)
react 书写 样式
- 基于class 但是 react 必须 className 代替class
- 基于内联样式 style style = {obj} 遵循 驼峰命名
style = {backgroundColor:“red”,fontSize:20}
lineHeight:‘20px’ 必须带单位 - 全局变量 外部样式 原型链挂载
基于原生Js 编写事件
addEventListener(“click”,fn,true/false); false/true 冒泡/捕获 默认false 冒泡
onclick onchange onfocusjquery
$(“div”).on(“click”) $(“div”).off(“click”)
$(‘div’).bind(‘click’) 绑定 $(‘div’).unbind(‘click’)事件委托 把事件绑定到父元素上 子元素触发事件 通过事件冒泡 让父元素代替子元素执行冒泡的事件
$(“div”).on(“click”,childnode,fn);
$(“div”).delegate(childnode,‘click’,fn)vue
v-on:click = “get()”
@input = “input($event)” $event 事件对象react 绑定事件 驼峰命名
onClick
onChange
onInput
onMouseMove
onMouseDown
onMouseUp
onTouchStart
onTouchMove
onTouchEnd
onKeyPress
onKeyDown
onKeyUp绑定事件
- 全局变量 / 外部函数
- 组件内部自定义函数
- 原型链挂载
-
/*
-
react 数据传递载体 props 属性 state 状态 组件之间数据交互
-
props
a. props 默认从组件外部(父组件)传入,props 也能在组件内部初始化定义 getDefaultProps
b. 组件内部 通过生命周期钩子函数 getDefaultProps (已废弃 ) App.defaultProps = {}
c. props 一般不允许被修改 props 只用来传递数据
d. props 接收 对象 常量 函数 数组
e. props 在组件内部 通过 this.props 来获取 key-value
*/
// PropTypes 校验Props
// optionalArray: PropTypes.array,
// optionalBool: PropTypes.bool,
// optionalFunc: PropTypes.func,
// optionalNumber: PropTypes.number,
// optionalObject: PropTypes.object,
// optionalString: PropTypes.string,
// optionalSymbol: PropTypes.symbol,
// 校验 props 接收正确的格式类型的数据
/*
state 状态 react 组件数据交互的载体 状态用来修改的
- state 不能在组件外部定义 不能在组件外部 修改 只能在组件内部定义声明 只能在内部修改
- state 用来被修改的 this.state 获取 state, this.setState() 来修改 state
- state 在组件内部的 getInitialState 来初始化定义 state ,必须返回一个对象
- state 修改 setState 这个方法会修改 state 会重新执行 组件内部的 render方法 , 会触发页面的
二次渲染 虚拟DOM 会根据react 的 diff 算法 得到新的虚拟DOM 最后的批量的更新
*/
/*
组件之间的通信
- 父子 组件
- 兄弟组件
props 传递数据
state 修改数据
父组件如何修改子组件
父组件把组件的state 当着子组件的props 传递给子组件
父组件修改 state 会二次render 子组件接收到变化的 props 从而实现子组件修改
ref this.refs 对象获取
- ref 作用于DOM 元素 指向这个真实的DOM元素
- ref 作用于组件 指向这个组件对象
/
/
react 组件的生命周期
含义 组件从初始化渲染到被移除或者销毁的过程 成为组件的生命周期
- 每个组件都有生命周期
- react 通过组件的生命周期钩子函数来管理 组件
- 系统 某些状态和参数发生改变的时候,系统立马去通知 对应处理的函数叫做钩子函数
hooks 钩子函数 允许在特定的时期添加用户自己的代码 不同的阶段添加自己的逻辑代码
react 组件的生命周期 分为三个阶段
1.mount 组件的初始化 从虚拟DOM 渲染成为真实DOM 的过程
2.update 组件的数据变化 组件的state 更新 导致二次渲染的过程
3.unmount 组件销毁 组件因为路由切换而销毁 (浏览器的垃圾回收机制 )
mounted 组件载入阶段 (钩子函数)
1.getDefaultProps 设置组件默认的props 废弃
2.getInitialState 设置组件默认的state 废弃
3.componentWillMount 在jsx被渲染到页面之前被调用
4.render 渲染函数是react中默认的函数
5.componentDidMount jsx被渲染到页面后被调用
*/
/*
update 组件数据更新阶段 组件修改 state 组件接收的props发送改变 都会进入 update 阶段
- componentWillReceiveProps(nextProps) 接收变化的props
- shouldComponentUpdate 询问是否更新 true 更新 false 不更新
- componentWillUpdate 组件即将更新
- render 组件开始二次渲染 update
- componentDidUpdate 组件更新渲染数据完毕
*/
// 组件销毁移除 路由切换
// componentWillUnmount 这个函数几乎不会使用到,因为浏览器本身具有垃圾回收机制
props 传递数据 层级传递
context 传递数据 隔空传递
PropTypes 校验Props
optionalArray: React.PropTypes.array,
optionalBool: React.PropTypes.bool,
optionalFunc: React.PropTypes.func,
optionalNumber: React.PropTypes.number,
optionalObject: React.PropTypes.object,
optionalString: React.PropTypes.string,
optionalSymbol: React.PropTypes.symbol,
移动端适配
100%布局 弹性盒布局
vw / vh / rem 布局
rem === 根节点的字体大小 1rem = 100px
其实 就是 等比缩放
假定 设计稿 750px 当前 html 字体大小 1rem = 100px;
到时候 手机 设备宽 改变 得到 变化的 rem
750: 100px = 375 : X ==> X = 375*100/750 = 50px;
750: 100px = 320: X ==> X = 320*100/750 = 42.7px
等比缩放
设计稿宽 跟 当前设计稿假定 的 rem 比例等于 当前手机设备的宽 和当前设备设备的rem 的比例