React

1.前端三大框架

Angular.js

出来比较早也支持组件化,支持ts

 Vue.js 

最火的一门前端框架,他是中国人开发的,对我们来说,文档中文

React.js

流行设计有些

组件化

拆分小组件,最后组装,方便了组件的复用

模块化

从代码的角度去分析问题,吧我们编程时候的业务逻辑,分割到不同的模块中来进行开发,这样能够实现代码的重用

vue 组件化,.vue组件模板化,浏览器不是变,所以在运行前编译为真正的组件

<template> ui

<script> 业务逻辑和数据

<style> 样式

React组件,在js中定义,组件并没有把一个组件拆分为三部分,而是全部使用JS来实现一个组件(结构,样式,业务逻辑是混合在js里面)

开发团队

React facebook

vue,结合week 移动开发

react,react-native 移动开发


 DOM的本质是什么:就是用JS表示的UI元素

+ DOM和虚拟DOM的区别:

- DOM是由浏览器中的JS提供功能,所以我们只能人为的使用 浏览器提供的固定的API来操作DOM对象;

- 虚拟DOM:并不是由浏览器提供的,而是我们程序员手动模拟实现的,类似于浏览器中的DOM,但是有着本质的区别;

- 为什么要实现虚拟DOM:

- 什么是React中的虚拟DOM:

- 虚拟DOM的目的:

![虚拟DOM - 表格排序案例](images/虚拟DOM引入图片.png)




- tree diff:新旧DOM树,逐层对比的方式,就叫做 tree diff,每当我们从前到后,把所有层的节点对比完后,必然能够找到那些 需要被更新的元素;

- component diff:在对比每一层的时候,组件之间的对比,叫做 component diff;当对比组件的时候,如果两个组件的类型相同,则暂时认为这个组件不需要被更新,如果组件的类型不同,则立即将旧组件移除,新建一个组件,替换到被移除的位置;

- element diff:在组件中,每个元素之间也要进行对比,那么,元素级别的对比,叫做 element diff;

- key:key这个属性,可以把 页面上的 DOM节点 和 虚拟DOM中的对象,做一层关联关系;

## React项目的创建

1. 运行 `cnpm i react react-dom -S` 安装包

2. 在项目中导入两个相关的包:

```

// 1. 在 React 学习中,需要安装 两个包 react react-dom

// 1.1 react 这个包,是专门用来创建React组件、组件生命周期等这些东西的;

// 1.2 react-dom 里面主要封装了和 DOM 操作相关的包,比如,要把 组件渲染到页面上

import React from 'react'

import ReactDOM from 'react-dom'


react-native 不能用cnpm安装

jsx语法

 注意,哪怕在js中可以写jsx语法了。但是jsx在内部运行的时候,也是先把类似于html的标签代码转换为了react.createElement

运行 cnpm i babel-preset-react -D

.babelrc中配置

 "presets": ["env", "stage-0", "react"],



## JSX语法

1. 如要要使用 JSX 语法,必须先运行 `cnpm i babel-preset-react -D`,然后再 `.babelrc` 中添加 语法配置;

2. JSX语法的本质:还是以 React.createElement 的形式来实现的,并没有直接把 用户写的 HTML代码,渲染到页面上;

3. 如果要在 JSX 语法内部,书写 JS 代码了,那么,所有的JS代码,必须写到 {} 内部;

4. 当 编译引擎,在编译JSX代码的时候,如果遇到了`<`那么就把它当作 HTML代码去编译,如果遇到了 `{}` 就把 花括号内部的代码当作 普通JS代码去编译;

5. 在{}内部,可以写任何符合JS规范的代码;

6. 在JSX中,如果要为元素添加`class`属性了,那么,必须写成`className`,因为 `class`在ES6中是一个关键字;和`class`类似,label标签的 `for` 属性需要替换为 `htmlFor`.

7. 在JSX创建DOM的时候,所有的节点,必须有唯一的根元素进行包裹;

8. 如果要写注释了,注释必须放到 {} 内部

//在react创建组件

function Hello{

retun null

}

React在解析首字母必须大写会按组件解析,小写按标签解析

这里的...obj语法,是Es6中的属性跨三,表示,把这个对象上的所有属性,展开了,放到这个位置

在组建中如果想要使用外部传递过来的数据,必须显示在构造函数参数列表中,定义props属性来接收,为只读属性值不能改变

webpack.config.js配置jsx

 { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ }

constructor(props){

super(props)

}

使用function构造函数创建的组件,内部没有state

使用class关键字,创建的组件,内部,除了又this.props这个属性之外,还有一个专门用于存放自己私有数据的this.state属性,这个state是可读可写的,class创建的还有生命周期函数


什么时候使用有状态的什么时候使用无状态的

Css模块化

css-loader?modules&localIdentName=[name]_[local]-[hash:8]

css模块化后,这里所有的类名都是私有的如果想暴露出去 :global()包起来


概念:在组件创建、到加载到页面上运行、以及组件被销毁的过程中,总是伴随着各种各样的事件,这些在组件特定时期,触发的事件,统称为 组件的生命周期;

+ 组件生命周期分为三部分:

- **组件创建阶段**:组件创建阶段的生命周期函数,有一个显著的特点:创建阶段的生命周期函数,在组件的一辈子中,只执行一次;

> componentWillMount: 组件将要被挂载,此时还没有开始渲染虚拟DOM

> render:第一次开始渲染真正的虚拟DOM,当render执行完,内存中就有了完整的虚拟DOM了

> componentDidMount: 组件完成了挂载,此时,组件已经显示到了页面上,当这个方法执行完,组件就进入都了 运行中 的状态


- **组件运行阶段**:也有一个显著的特点,根据组件的state和props的改变,有选择性的触发0次或多次;

> componentWillReceiveProps: 组件将要接收新属性,此时,只要这个方法被触发,就证明父组件为当前子组件传递了新的属性值;

> shouldComponentUpdate: 组件是否需要被更新,此时,组件尚未被更新,但是,state 和 props 肯定是最新的

> componentWillUpdate: 组件将要被更新,此时,尚未开始更新,内存中的虚拟DOM树还是旧的

> render: 此时,又要重新根据最新的 state 和 props 重新渲染一棵内存中的 虚拟DOM树,当 render 调用完毕,内存中的旧DOM树,已经被新DOM树替换了!此时页面还是旧的

> componentDidUpdate: 此时,页面又被重新渲染了,state 和 虚拟DOM 和 页面已经完全保持同步


- **组件销毁阶段**:也有一个显著的特点,一辈子只执行一次;

> componentWillUnmount: 组件将要被卸载,此时组件还可以正常使用;

static defaultProps={

initcount:0

}

使用prop-types 进行props属性

static propTypes{


}


shouldComponentUpdate()返回true or false

返回false 页面没有更新,但是组件的state的会被改变,(奇数更新,偶数不跟新)案例

经过打印测试发现,在shouldCoponentUpdate中,通过this.state。count拿到的值,是上一次的旧数据,并不是最新的

通过nextProps,nextState形参获取最新的

ref="ddd" 属性获取dom

this.refs.ddd

&&运算去除undefine  this.person&& this.person.name


componentWillReceiveProps (nextProps) 第一次加载不会触发

只有当父组件通过某些事件,重新修改了传递给子组件的props数据之后才会触发

nextProps获取最新的



传参

bind作用,为前面的函数,修改函数内部的this,指向,

让函数内部的this,指向bind参数列表中的第一个参数

bind和call/apply区别

call/apply修改完this指向后悔立即调用前面的函数,但是bind只是修改this指向

bind(this,参数)

绑定this并传参,在构造函数中

注意当为一个函数,调用bind改变了this指向后,bind函数滴啊用的结果,有一个返回值,这个值,就是被改变this指向后的函数引用,注意bind不会修改原函数的this指向

this.changeMsg2=this.changeMsg2.bind(this,参数)必须接收,不接受相当于没有改变

绑定的第三种方式,箭头函数

箭头函数会把外面的实例绑定到方法里面

οnclick={

()=>this.chanMsg3(“ggg”,"fddd")

}

如果事件中要传参数,我们绑定时事件的时候把传参的函数放到一个箭头函数中去

react 默认不支持双向数据绑定,react只支持把数据从state上传输到页面,但是无法自动实现数据从页面到state中进行保存,也就是React不支持数据的自动逆向传输


{/* 在 Vue 中,有 v-model 指令来实现双向数据绑定,但是,在 React 中, 根本没有指令的概念,因此React 默认也不支持 双向数据绑定 */}
{/* React 只支持,把数据从 state 上传输到 页面,但是,无法自动实现数据从 页面 传输到 state 中 进行保存,也就是,React 不支持数据的自动逆向传输, 只是实现了数据的单向绑定 */}
{/* 注意:如果为 表单元素,提供了 value 属性绑定,那么,必须同时为 表单元素 绑定 readOnly, 或者提供要给 onChange 事件 */}
{/* 如果提供了readOnly,表示这个元素只读的不能被修改 */}
{/* 如果提供了onChange 表示,这个元素的值可以被修改,但是,要自己定义修改的逻辑 */}
/ console.log('ok');
// 如果想让 文本框在触发 onChange 的时候,同时把文本框最新的值,保存到 state 中,那么,我们需要手动调用 this.setState

// 获取文本框中 最新文本的3种方式:
// 1. 使用 document.getElementById 来拿
// 2. 使用 ref 来拿
// console.log(this.refs.txt.value);
// 3. 使用 事件对象的 参数 e 来拿 e.target 就表示触发 这个事件的 事件源对象,得到的是一个原生的JS DOM 对象
// console.log(e.target.value);


在父组件上,直接共享一个context对象,子孙组件不需要做层传递属性了 


// 最外层的父组件
export default class Com1 extends React.Component {
constructor(props) {
super(props)

this.state = {
color: 'red'
}
}

// getChildContextTypes
// 1. 在 父组件中,定义一个 function,这个function 有个固定的名称,叫做 getChildContext ,内部,必须 返回一个 对象,这个对象,就是要共享给 所有子孙自建的 数据
getChildContext() {
return {
color: this.state.color
}
}

// 2. 使用 属性校验,规定一下传递给子组件的 数据类型, 需要定义 一个 静态的(static) childContextTypes(固定名称,不要改)
static childContextTypes = {
color: ReactTypes.string // 规定了 传递给子组件的 数据类型
}


render() {
return <div>
<h1>这是 父组件 </h1>
<Com2></Com2>
</div>
}
}



// 中间的子组件
class Com2 extends React.Component {
render() {
return <div>
<h3>这是 子组件 </h3>
<Com3></Com3>
</div>
}
}



// 内部的孙子组件
class Com3 extends React.Component {

// 3. 上来之后,先来个属性校验,去校验一下父组件传递过来的 参数类型
static contextTypes = {
color: ReactTypes.string // 这里,如果子组件,想要使用 父组件通过 context 共享的数据,那么在使用之前,一定要先 做一下数据类型校验
}

render() {
return <div>
<h5 style={{ color: this.context.color }}>这是 孙子组件 --- {this.context.color} </h5>

</div>
}
}











转载于:https://juejin.im/post/5d05a0a2e51d4550a629b271

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值