脚手架:javascript
解压两个文件:在项目的根目录下执行npm install////npm I 会按照package.json的配置安装依赖模块。css
安装完成后,会出现一个node_modules,里面是安装的全部依赖的模块。html
都是项目的根目录。前端
npm installjava
代理是哪里进去哪里出来。node
.babelrc: babel转译的配置文件。 (放的是预设值)环境信息,插件等。react
.gitignore(忽略的信息)webpack
Index.html(网页的HTML显示信息,发布的站点根目录)ios
Jsconfig.json(vscode本身所用的)git
LICENSE()
.npmrc() 镜像库
Package.js(依赖信息)
README.md()
Src(js的插件信息)
App.js
Appstate.js
Index.html
Node_moudles(npm包管理器设置之后全部的依赖文件)
Webpack.config.dev.js 开发时候使用的
Webpack.config.prod.js 生产环境使用的
Npm 产生的文件,里面记录项目信息,全部项目依赖。
里面包括的是版本等信息。
Start:启动webpack的dev server开发用的web server,提供的静态文件加载、自动刷新和热替换HMR(hot module replacement)
HMR能够在应用程序运行中替换,添加和删除模块,不须要从新加载模块,只是变化部分替换掉,不用HMR则自动刷新页面。
--HOT 启动HMR
--inline默认模式,使用HMR的时候建议使用inline模式,热替换时候会有消息显示在控制台。
Build使用webpack构建打包,对应npm run build
开发时候的依赖,不会打包到目标文件中。例如转译代码等。不必到生产中去。
Dependencies运行的时候的依赖必须带到项目中去,
版本号:
指定安装版本号:
~安装指定中和最新的版本。
^安装指定中最高的版本,不低于指定的版本。*******建议经常使用
Latest:最新版本。
Babel转译的。
Css样式:
Css-loader样式表相关的模块。
React-hot-loader热加载插件。
运行时候的依赖:
Antd ant design基于react实现,后台管理较方便。
Axios 异步请求
Polyfiill解决浏览器api不支持的问题,磨平差别化。
React开发的主框架。
React-router路由
React-router-dom dom绑定路由
Mobx状态管理库,透明化
Mobx-react mobx-react-devtools mobx和react结合的模块。
React和mobx是一个强强联合。
Babel转译的配置文件
(1)webpack.config.dev.js
符合commonjs的模块。
Devtools:’source-map’
调试时候映射处理。
Entry入口:从入口直接找到须要打包的文件。
Output输出:
Resolve解析
Module模块
Test匹配条件的。
Exclude排除的,
Use使用模块的useentries列表中的loader,
Rules中.js结尾的但不在node_modules目录的文件使用转译babel-loader和热加载loader。
加载器:
style-loader经过<style>标签吧css添加到dom中。
Css-loader加载css
Less-loader对less的支持
Less:控制h2标记的。
Devserver,开发使用的server
Compress启动gzip
Port启动端口3000
Hot启动HMR
Proxy执行访问/api开头路径都代理到http://127.0.0.0:8080中
Jsconfig.json是vscode的配置文件,覆盖当前配置。
上面的配置文件,须要更改name,version,description,须要修改repository仓库地址,须要修改author、license信息。修改完成后,进行开发。
App-xxxxx的文档必须放在根目录,对于Windows下的是磁盘的根目录。
npm start
React是Facebook开发的并开源的前端框架。
2013年开源的,react解决的是前端的MVC框架中的view视图层的问题。
DOM是什么?
DOM(文档对象模型document object model)
是HTML和xml文档,把其解析成为dom对象,展现成为树的模型。
Js在浏览器端多数状况下都是操做dom树的。
选择节点问题,经过id等进行查找等。
The document
The dom tree
将网页全部内容映射到一颗树形的结构的层级对象模型上,浏览器提供对dom支持,用户能够用脚本调用dom api来动态的修改dom节点,从而达到修改网页的目的,这种修改在浏览器中完成,浏览器胡根据dom的修改重绘dom的节点部分。
修改dom从新渲染的代价比较高,前端框架为了提升效率,尽可能减小DOM的重绘,提出了virtual DOM,全部的修改都是如今的virtual dom上面完成,经过比较算法,找出浏览器和dom之间的差别,使用这个差别操做dom,浏览器只是须要渲染这个部分变化就好了。
React实现了dom diff算法能够高效比对vir dom和 dom的差别。
Jsx是一种Javascript和xml混写的语法,是Javascript的扩展。
直接插入HTML语句等。
import React from 'react';
import ReactDOM from 'react-dom';
// import { render } from 'react-dom';
// import { AppContainer } from 'react-hot-loader';
// import AppState from './AppState';
// import App from './App';
// const appState = new AppState();
// render(
// <AppContainer>
// <App appState={appState} />
// </AppContainer>,
// document.getElementById('root')
// );
// if (module.hot) {
// module.hot.accept('./App', () => { render(App) })
// }
class Root extends React.Component{
render(){
return <div>javascript excise</div>;
}
}
ReactDOM.render(<Root/>,document.getElementById('root'));
Return的必须是jsx的语法。单标计必须是封口的。
Render()渲染函数,必须有return值,必须有顶级元素返回,全部元素必须闭合。
单行省略小括号,多好使用小括号。
class Root extends React.Component{
render(){
return <div>javascript <br/> excise</div>;
}
}
<br/>换行符
class Root extends React.Component{
render(){
return React.createElement('div',null,'javascript');
//return <div>javascript <br/> excise</div>;
}
}
//ReactDOM.render(<Root/>,document.getElementById('root'));
ReactDom.render(React.createElement(Root),document.getElementById('root'));
更改属性的值:大括号等信息。
增长一个子元素:
class SubEle extends React.Component{
render(){
return <div>Sub content</div>
}
}
class Root extends React.Component{
render(){
return (
<div>
<h2>welcome to study</h2>
<br/>
<SubEle/>
</div>);
}
}
ReactDOM.render(<Root/>,document.getElementById('root'))
React组件的render函数return,只能是一个顶级元素。
Jsx语法是XML,要求全部元素必须闭合,<br/> 不能是<br>
标签中首字母小写就是HTML标记,首字母大写就是组件。
要求严格的标记,要求全部标签必须闭合,br也应该写成<br />,/前面留一个空格。
单行省略小括号,多行必须使用小括号。
元素有嵌套的,多行,缩进。
Jsx表达式:使用{}括起来,若是大括号内使用了引号,会当作字符串处理。
每个react组件都有一个状态变量state,是一个JavaScript对象,为期定义属性保存值。
状态变化了,会出发UI从新渲染,使用setstate方法从新修改state的值。
State是组件内部使用的,是私有属性。
import React from 'react';
import ReactDOM from 'react-dom';
class Root extends React.Component{
state = {
p1: 'abc',
p2:'.com'
};
render(){
this.state.p1 = 'www.abc'
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
</div>
);
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
//this.state.p1 = 'www.abc'
改成下面的,不容许,不容许对更新中的state进行setState
//this.setState({p1:'www.ab'}) //不容许这样修改,控制台会报错,
使用延时函数:setTimeout(里面是一个函数)
setTimeout(()=>this.setState({p1:'www.abdd'}),5000)
class Root extends React.Component{
state = {
p1: 'abc',
p2:'.com'
};
render(){
//this.state.p1 = 'www.abc'
//this.setState({p1:'www.ab'}) //不容许这样修改,控制台会报错,
setTimeout(()=>this.setState({p1:'www.abdd'}),5000)
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
</div>
);s
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
Div的id是t1,鼠标按下事件就捆绑了一个函数,只要鼠标按下就会触发调用getEventTrigger函数,浏览器就会给其送一个参数event,event是时间对象,当时间触发的时候,event包含触发这个时间的对象。
属性 |
此事件发生在什么时候 |
Onabort |
图像的加载被中断 |
Onblur |
元素失去焦点 |
Onchange |
域的内容被改变 |
Onclick |
当用户点击某个对象时候调用的时间句柄 |
Ondbclick |
当用户双击某个对象时候调用的事件句柄 |
Onerror |
在加载文档或图像时候发生错误 |
Onfocus |
元素得到焦点 |
Onkeydown |
某个键盘键被按下 |
Onkeypress |
某个键盘按键被按下并松开 |
Onkeyup |
某个按键被松开 |
Onload |
一张页面或一幅图像完成加载 |
Onmousedown |
鼠标按钮被按下 |
Onmousemove |
鼠标按键被移动 |
Onmouseout |
鼠标从某元素移开 |
Onmouseover |
鼠标移到某个元素之上 |
Onmouseup |
鼠标按键被松开 |
Onreset |
重置按钮被点击 |
Onresize |
窗口或框架被从新调整大小 |
Onselect |
文本被选中 |
Onsubmit |
确认按钮被点击 |
Onunload |
用户退出页面 |
import React from 'react';
import ReactDOM from 'react-dom';
class Toggle extends React.Component{
state = {flag:true};
handleClick(event){
console.log(event.target.id)
console.log(event.target === this);
console.log(this)
console.log(this.state)
this.setState({flag:!this.state.flag})
}
render(){
return <div id="t1" onClick={this.handleClick.bind(this)}>
点击这句话,会触发一个事件1。{this.state.flag.toString()}
</div>;
}
}
class Root extends React.Component{
state = {
p1: 'abc',
p2:'.com'
};
render(){
//this.state.p1 = 'www.abc'
//this.setState({p1:'www.ab'}) //不容许这样修改,控制台会报错,
setTimeout(()=>this.setState({p1:'www.abdd'}),5000)
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle />
</div>
);
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
Toggle类
有本身的state属性,当render完成后,网页上有一个div标签捆绑了一个click事件的函数,div标签内有文本内容。
若是用过点击左键,就触发了click方法关联的handleClick函数,在这个函数里将状态值改变。
状态值state的改变将引起render重绘。
{this.handleClick.bind(this)},不能外加引号。
This.handleClick.bind(this)必定要绑定this,不然当触发捆绑的函数时候,this是函数执行的上下文决定的,this已经不是触发事件的对象了。
Console.log(event.target.id)取回的产生事件的对象的id,不是封装的组件的对象,因此,console.log(event.target===this)是false,这个this是经过绑定过来的。
React的事件:
使用小驼峰命名。
使用jsx表达式,表达式中要指定事件处理函数。
不能使用return false,若是要阻止事件默认行为,使用event.preventDefault()
Id是惟一的,坚定不能有重复的。
把react组件当作标签使用,能够为其增长属性:
组件之间利用state或者传parent传递参数
修改属性是不能够的,由于是只读的this.props.name.
import React from 'react';
import ReactDOM from 'react-dom';
class Toggle extends React.Component{
state = {flag:true};
handleClick(event){
console.log(event.target.id)
console.log(event.target === this);
console.log(this)
console.log(this.state)
this.setState({flag:!this.state.flag})
}
render(){
return <div id="t1" onClick={this.handleClick.bind(this)}>
点击这句话,会触发一个事件1。{this.state.flag.toString()}
{this.props.school}{this.props.age}
<br />
{this.props.parent.state.p1}
{this.props.children}
</div>;
}
}
class Toggle1 extends React.Component{
state = {flag:true};
handleClick(event){
console.log(event.target.id)
console.log(event.target === this);
console.log(this)
console.log(this.state)
this.setState({flag:!this.state.flag})
}
render(){
return <div id="t2" onClick={this.handleClick.bind(this)}>
点击这句话,会触发一个事件2。{this.state.flag.toString()}
<br />
{this.props.name}
<hr />
{this.props.age}
{this.props.parent.state.p2}
</div>;
}
}
class Root extends React.Component{
state = {
p1: 'abc',
p2:'.com'
};
render(){
//this.state.p1 = 'www.abc'
//this.setState({p1:'www.ab'}) //不容许这样修改,控制台会报错,
setTimeout(()=>this.setState({p1:'www.abdd'}),5000)
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle school='abc' age= '20' parent={this} >
</Toggle>
<Toggle1 name='tom' age= '10' parent={this}/>
</div>
);
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
注意访问parent送进去的是this,访问实例自己的属性的方式是利用this.props.state.p1的值
利用construc(props)。
Super()调用父类的。
只要extends的,必须利用super()调用。Props做为参数传入。
import React from 'react';
import ReactDOM from 'react-dom';
class Toggle extends React.Component{
constructor(props){
console.log('Toggle')
super(props)
this.state = {flag:true};
}
handleClick(event){
console.log(event.target.id)
console.log(event.target === this);
console.log(this)
console.log(this.state)
this.setState({flag:!this.state.flag})
}
render(){
return <div id="t1" onClick={this.handleClick.bind(this)}>
点击这句话,会触发一个事件1。{this.state.flag.toString()}
{this.props.school}{this.props.age}
<br />
{this.props.parent.state.p1}
{this.props.children}
</div>;
}
}
class Toggle1 extends React.Component{
constructor(props){
console.log('Toggle1')
super(props)
this.state = {flag:true};
}
handleClick(event){
console.log(event.target.id)
console.log(event.target === this);
console.log(this)
console.log(this.state)
this.setState({flag:!this.state.flag})
}
render(){
return <div id="t2" onClick={this.handleClick.bind(this)}>
点击这句话,会触发一个事件2。{this.state.flag.toString()}
<br />
{this.props.name}
<hr />
{this.props.age}
{this.props.parent.state.p2}
</div>;
}
}
class Root extends React.Component{
state = {
p1: 'abc',
p2:'.com'
};
render(){
//this.state.p1 = 'www.abc'
//this.setState({p1:'www.ab'}) //不容许这样修改,控制台会报错,
setTimeout(()=>this.setState({p1:'www.abdd'}),5000)
return (
<div>
<div>welcome to {this.state.p1}{this.state.p2}</div>
<br />
<Toggle school='abc' age= '20' parent={this} >
</Toggle>
<Toggle1 name='tom' age= '10' parent={this}/>
</div>
);
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
组件的声明周期可分为三个状态。
Mounting:已插入真实dom。
Updating:正在被从新渲染。
Unmounting:已移除真实dom。
方法以下:
(1)装载组件触发:
Componentwillmount在渲染前调用,在客户端也在服务器端,指挥在装载前调用一次。
Componentdidmount:在第一次渲染后调用,只要是在客户端,以后的组件已经生成对应的dom结构,能够经过this.getdomnode()来进行访问, 想与其余的Javascript框架一块儿使用,在这个方法中调用setTimeout,setinterval或者发送ajax请求等操做,只是在装载完后调用一次,在render以后。
(2)更新组件触发,这些方法不会再首次render组件的周期调用。
Componentwillreceiveprops(nextprops)在组件接受到一个新的prop时候被调用,在初始化render时候不会调用。
Shouldcomponentupdae(nextprops,nextstate)返回布尔值,在组件接受到新的Props或者state时候被调用,在初始化或者使用forceupdate时候不被调用。(若是设置为false,就不容许更新组件。)
Componentwillupdate(nextprops,nextstate)在组件接受到新的props或者state还没render时候被调用,在初始化不会调用。
Componentdidupdate(prevprops,prevstate)在组件完成后更新后当即调用,在初始化时候不会被调用。
(3)卸载组件触发
ComponentwillUNmount在组件从dom中移除的时候当即被调用
图中,constructor构造器是最先执行的函数,触发更新生命周期的函数,须要更新state或者props。
import React from 'react';
import ReactDOM from 'react-dom';
class Sub extends React.Component{
constructor(props){
console.log('sub con')
super(props)
this.state = {count:0}
}
handleClick(event){
this.setState({count:this.state.count + 1});
}
render(){
console.log('sub render')
return <div id='sub'onClick={this.handleClick.bind(this)}>
Sub's count = {this.state.count}
</ div>
}
componentWillMount(){
//第一次render以前
console.log('sub componentwillmount')
}
componentDidMount(){
//第一次render以后
console.log('sub componentDidMount')
}
componentWillUnmount(){
//清理工做
console.log('sub componentWillUnmount ')
}
}
class Root extends React.Component{
constructor(props){
console.log('root con')
super(props)
this.state = {}
}
render(){
return <div>
<Sub />
</ div>
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
顺序是constructor =》 componentwillmount =》 render =》 componentdidmount –state或props改变,render。
import React from 'react';
import ReactDOM from 'react-dom';
import { ENGINE_METHOD_DIGESTS } from 'constants';
class Sub extends React.Component{
constructor(props){
console.log('sub con')
super(props)
this.state = {count:0}
}
handleClick(event){
this.setState({count:this.count + 1});
}
render(){
console.log('sub render')
return <div id='sub'onClick={this.handleClick.bind(this)}>
Sub's count = {this.state.count}
<a style={{height:200+'px',color:'red',backgroundColor:'#f0f0f0'}} >
</ a>
</ div>
}
componentWillMount(){
//第一次render以前
console.log('sub componentwillmount')
}
componentDidMount(){
//第一次render以后
console.log('sub componentDidMount')
}
componentWillUnmount(){
//清理工做
console.log('sub componentWillUnmount ')
}
componentWillReceiveProps(nextProps){
//props变动时候,接受新的props,交给shouldComponentUpdate
//props组件内只读,只能从外部改变
console.log(this.props)
console.log(nextProps)
console.log('sub componentWillReceiveProps',this.state.count);
}
shouldComponentUpdate(nextProps,nextState){
//是否组件更新,props或state方式改变时候,返回布尔值,true才会更新
console.log('sub shouldComponentUpdate',this.state.count,nextState)
return true
}
componentWillUpdate(nextProps,nextState){
//赞成更新后,真正更新以前,调用render
console.log('sub componentWillUpdate',this.state.count,nextState)
}
componentDidUpdate(prevProps,prevState){
//赞成更新后,真正更新后,在render以后调用。
console.log('sub componentDidUpdate',this.state.count,prevState)
}
}
class Root extends React.Component{
constructor(props){
console.log('root con')
super(props)
this.state = {}
}
render(){
return <div>
<Sub />
</ div>
}
}
ReactDOM.render(<Root />,document.getElementById('root'))
Componentwillmount第一次装载,在首次render以前,例如控制state、props。
Componentdidmount第一次装载结束,在首次render以后,控制state,props。
Componentwillreceiveprops在组件内部,props是只读不可变的,这个函数接受到新的props,能够对props作一些处理,this.props={name:‘root’}这就是偷梁换柱,componentwillreceiveprops触发,也会走shouldcomponentupdate。
Shouldcomponentupdate判断是否须要组件更新,是否render,精确的控制渲染,提升性能。
Componentwillupdate除了首次render以外,每次render前执行,componentdidupdate在render以后调用。
componentWillMount(){
//第一次render以前
console.log('sub componentwillmount')
}
componentDidMount(){
//第一次render以后
console.log('sub componentDidMount')
}
componentWillUnmount(){
//清理工做
console.log('sub componentWillUnmount ')
}
componentWillReceiveProps(nextProps){
//props变动时候,接受新的props,交给shouldComponentUpdate
//props组件内只读,只能从外部改变
console.log(this.props)
console.log(nextProps)
console.log('sub componentWillReceiveProps',this.state.count);
}
shouldComponentUpdate(nextProps,nextState){
//是否组件更新,props或state方式改变时候,返回布尔值,true才会更新
console.log('sub shouldComponentUpdate',this.state.count,nextState)
return true
}
componentWillUpdate(nextProps,nextState){
//赞成更新后,真正更新以前,调用render
console.log('sub componentWillUpdate',this.state.count,nextState)
}
componentDidUpdate(prevProps,prevState){
//赞成更新后,真正更新后,在render以后调用。
console.log('sub componentDidUpdate',this.state.count,prevState)
}
}
也叫作函数式组件。
许多时候组件简单不须要state状态,也不须要声明周期函数,无条件组件很好的知足了须要,无状态组件提供了一个参数props,返回一个react元素,无状态组件函数自己就是render函数。
import React from 'react';
import ReactDOM from 'react-dom';
//let Root = props =><div>{props.shoolname}</div>;
//ReactDOM.render(<Root shoolname='abc' />,document.getElementById('root'))
function Root(props){
return <div> {props.name}</div>
}
ReactDOM.render(<Root name='bcd'/>,document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = function (Component){
function _wrapper(props){
return (
<div>
{props.name}
<hr />
<Component />
</ div>
)
}
return _wrapper
}
let Root = props =><div>Root</ div>
let NeeComp = wrapper(Root)
ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = function (Component){
return props=>(
<div>
{props.name}
<hr />
<Component />
</ div>
)
}
let Root = props =><div>Root</ div>
let NeeComp = wrapper(Root)
ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = Component=> props =>(
<div>
{props.name}
<hr />
<Component />
</ div>
)
let Root = props =><div>Root</ div>
let NeeComp = wrapper(Root)
ReactDOM.render(<NeeComp name='abc' />,document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = Component=>props=>
(<div>
{props.aname}
<hr />
<Component />
</ div>
)
//let Root = props => <div>Root</ div>
@wrapper
class Root extends React.Component{
render(){
return <div> Root</ div>
}
}
let Newarpper = wrapper(Root)
ReactDOM.render(<Newarpper aname='abc' />,document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = Components=>props=>
(<div>
{props.aname}
<hr />
<Components {...props} />
</ div>
)
//let Root = props => <div>Root</ div>
@wrapper
class Root extends React.Component{
render(){
return <div> Root{this.props.aname}</ div>
}
}
//let Newarpper = wrapper(Root)
ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))
Root中也显示props.name的属性,使用 <Components {...props} />
增长属性等。
import React from 'react';
import ReactDOM from 'react-dom';
let wrapper = id => Components=>props=>
(<div id = {id}>
{props.aname}
<hr />
<Components {...props} />
</ div>
)
//let Root = props => <div>Root</ div>
@wrapper('wrapper')
class Root extends React.Component{
render(){
return <div> Root{this.props.aname}</ div>
}
}
//let Newarpper = wrapper(Root)
ReactDOM.render(<Root aname='abc' />,document.getElementById('root'))
函数后面不能加括号调用,由于加括号返回的不是组件,而是render函数须要的内容。
要求返回的是组件,组件函数。