1. MVC的简介
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。
2.Vuex 和 Redux 的区别
Redux 使用的是不可变数据,而Vuex的数据是可变的。Redux每次都是用新的state替换旧的state,而Vuex是直接修改
Redux 在检测数据变化的时候,是通过的方式比较差异的,而其实和的原理一样,是通过来比较的(如果看源码会知道,其实他内部直接创建一个实例用来跟踪数据变化)
3. vue 和 react 监听数据的原理
vue中借助Object.defineProperty(getter setter) 做数据劫持
react很大程度上是通过比较对象的引用地址是否一致来看数据有没有变化(react中大量使用了不可变对象)
4. react 安装的目录
4.1 全局安装 webpack
1 | 2.1 构建webpack应用 |
4.2 创建webpack 应用
1.src文件夹 目录下的 index.html 、main.js
dist 文件夹 , webpack.config.js 配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18const path = require("path")
var htmlWebpackPlugin = require('html-webpack-plugin');
//webpack基于node构建的,所有用的是CommonJS模块化规范
module.exports = {
mode:"development",
entry: path.join(__dirname, './src/main.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
plugins: [
// 添加plugins节点配置插件
new htmlWebpackPlugin({
template:path.resolve(__dirname, 'src/index.html'),//模板路径
filename:'index.html'//自动生成的HTML文件的名称
})
],
}安装webpack和webpack-cli
1
2npm install webpack@4.27.1 -d
npm install webpack-cli -d 提供一些基本命令(比如webpack命令)4.index.html
1 | <head> |
- webpack
4.3.配置webpack-dev-serve
1 | #1.安装webpack-dev-serve |
4.4. 配置到内存中
1 | #1.安装html-webpack-plugin |
5. 遇到问题报错如下
1 | webpack-dev-server 不是内部或外部命令,也不是可运行 的程序 或批处理文件。 |
解决方法:
1 | npm i webpack-dev-server -d |
6.在 webpack 中使用 react
1.运行 npm install react react-dom -S 安装包
react: 专门用于创建组件和虚拟DOM的,同时组件的生命周期都在这个包中
react-dom: 专门进行DOM操作的,最主要的应用场景,就是`ReactDOM.render()
2.在html页面上准备一个容器
1 | <!-- 容器,将来,使用 React 创建的虚拟DOM元素,都会被渲染到这个指定的容器中 --> |
3.main.js 中引入包
1 | import React from 'react' // 创建组件、虚拟DOM元素,生命周期 |
4.创建虚拟 dom ,并且渲染到页面上去
1 | import React from 'react' // 创建组件、虚拟DOM元素,生命周期 |
7. 虚拟 dom的介绍(提高性能)
React.creatElement()相当于在内存中去构建 dom 。 当页面将要呈现的时候:
1.浏览器会获取整个页面的内容
2.构建dom树 document文档对象 (将页面上的标签,属性,文本转换成 dom 对象)
3.在内存就好像如下的形式:
1 | { |
4.新旧的dom进行差异对比,产生出差异dom,更新真实的dom,最后视图的更新
8.JSX 语法
1.jsx语法:是一种符合 xml 规范的js语法 extend markup language 可拓展标记语言
1 | 1.安装babel: |
2.安装能够识别转换jsx语法的包 babel-preset-react
1 | npm i babel-preset-react -D |
3.添加 .babelrc 文件配置文件如下:
1 | { |
4.在 webpack.config.js中添加
1 | module: { //要打包的第三方模块 |
优点:不仅帮助我们创建虚拟dom,还允许我们在jsx中嵌入js表达式,js语法
缺点:其本质依然是借助React.createElement()来创建虚拟dom
在jsx中嵌入js代码 , 需要用{} , 数组里的 需要 key = “1”
1 | {arrStr.map((item) => { |
9.组件&Props
纯函数
函数内部的代码不会对函数的入参以及函数外部的代码有任何的影响
React 的组件
2.1 函数组件(纯函数)
1
2
3
4
5
6
7
8
9
10import React from 'react' // 创建组件、虚拟DOM元素,生命周期
import ReactDOM from 'react-dom' // 把创建好的 组件 和 虚拟DOM 放到页面上展示的
//react 中创建组件的第一种方式:使用纯函数
function Hello(props) {
console.log(props)
return <div>{props.name}{props.age}</div>
}
export default Hello;
//导出到外部的main.js中去接收2.2//展开运算符{…obj},节省了代码
1
2
3ReactDOM.render(<Hello name={obj.name} age={obj.age} gender={obj.gender}></Hello>, document.getElementById('app'));
ReactDOM.render(<Hello {...obj}></Hello>, document.getElementById('app'));2.2 类组件
2.2.1 react中给我们了一个可以继承的类
1 | import React from 'react' |
9.1 两种创建的对比
- 函数组件:又叫无状态组件、木偶组件、非受控组件 (只有props,没有state,没有生命周期钩子函数)
- Class组件:有状态组件、智能组件、受控组件(有state,有生命周期钩子函数)
10. state 的数据更改问题
借助 this.setState 来修改 ,可以入参两个参数 ;
如果要立刻获取到更改完之后的数据,利用setState()函数指定第二个箭头参数 ,() => {}
1 | // 如果我们不基于以前的值来更改当前state的值,我们可以这样下 |
10.1 state 更新的原理
1 | setState本质是通过一个队列机制实现state更新的。 执行setState时,会将需要更新的state合并后放入状态队列,而不会立刻更新state,队列机制可以批量更新state。 |
this.setState(newState) |
---|
newState 存入pending 队列 (待定队列) |
判断是否处于 batch update (分批更新) |
1.保存在 dirtyComponents 中 (Y) 2.遍历dirtyComponents ,调用updateComponent,更新 pending state or props (N) |
10.1.1 如何知道已经被更新
- 回调函数
- 钩子函数
10.1.2 需要注意的地方
- setState可能会引发不必要的渲染(renders)
- setState无法完全掌控应用中所有组件的状态
10.2 updateComponent 中的 diff
(a) tree diff
1 | 其实传统diff算法就是对每个节点一一对比,循环遍历所有的子节点,然后判断子节点的更新状态。通过循环递归对节点进行依次对比,算法时间复杂度达到 O(n^3) ,n是树的节点数,这个有多可怕呢?——如果要展示1000个节点,得执行上亿次比较。即便是CPU快能执行30亿条命令,也**很难在一秒内**计算出差异。。 |
1 | 那么问题来了,如果DOM节点出现了跨层级操作,diff会咋办呢? |
(b) component diff
1 | React应用是基于组件构建的,对于组件的比较优化侧重于以下几点: |
1 | 如上图,当组件D → 组件G时,diff判断为不同类型的组件,虽然它们的结构相似甚至一样,diff仍然不会比较二者结构,会直接销毁D及其子节点,然后新建一个G相关的子tree,这显然会影响性能,官方虽然认定这种情况极少出现,但是开发中的这种现象造成的影响是非常大的。 |
(c) element diff
1 | 对于同一层级的element节点,diff提供了以下3种节点操作: |
1 | 一般diff在比较集合[A,B,C,D]和[B,A,D,C]的时候会进行全部对比,即按对应位置逐个比较,发现每个位置对应的元素都有所更新,则把旧集合全部移除,替换成新的集合,如上图,但是这样的操作在React中显然是复杂、低效、影响性能的操作,因为新集合中所有的元素都可以进行复用,无需删除重新创建,耗费性能和内存,只需要移动元素位置即可。 |
#####