第一、安装工程
第一步、创建一个文件夹并且cd到里面
执行创建react工程
npx create-react-app <项目名>
第二步、cd到生成react工程里面
执行启动服务
npm run start
成功了!
屏幕快照 2019-12-02 下午4.27.26.png 屏幕快照 2019-12-02 下午4.27.42.png
第二、数组遍历
function App() {
// const myDiv = React.createElement('div',{id:'myDiv',title:'xxxxx'},'哈哈好的')
let a = 55555;
let arr = [
<h1>哈哈哈哈</h1>,
<h2>范德萨发生的</h2>
]
let nameArr = ["您好","好哟","德丰丰"]
//方法一、map
// const newNameArr = nameArr.map(item=>{
// const newItem = <h1>{item}</h1>
// return newItem
// })
//方法二、forEach
// let H5Arr = []
// nameArr.forEach(item=>{
// const H5 = <h1>{item}</h1>
// H5Arr.push(H5)
// })
const myDiv = <h1>{a}</h1>
return (
//方法三
nameArr.map( item => <h1>{item}</h1>)
);
}
爆红,缺少key值
屏幕快照 2019-12-03 下午4.04.01.png
return (
//方法三
nameArr.map( item => <h1 key ={item}>{item}</h1>)
);
第三、props 参数传递 (function创建的组件需要接参数、class创建的组件可以通过this.props.xxx直接使用,不需要接收)
1、function创建的组件(哑组件或展示组件)
const dog = {
name:'lucky',
age:'66',
sex:'man'
}
function App() {
//传入参数
return <Mycomponent name = {dog.name} age = {dog.age} sex = {dog.sex}></Mycomponent>
}
//接收参数:props(形参可以随便写)) 注意:组件名称首字母必须大写
function Mycomponent(props){
return <h1>myComponent name:{props.name} age:{props.age} sex:{props.sex}</h1>
}
屏幕快照 2019-12-03 下午4.42.24.png
2 、class创建的组件
function Mycomponent(props){
// const hel = new Hello()
return <Hello name = "xxxx" age = "555"></Hello>//这种写法相当于 new 了一个 Hello 对象
}
class Hello extends React.Component{
render(){
return <h1>ddddddd name:{this.props.name} age:{this.props.age}</h1>
}
}
第四、展开运算符
const dog = {
name:'lucky',
age:'66',
sex:'man'
}
const cat = {
color: 'green',
...dog
}
屏幕快照 2019-12-03 下午4.58.34.png
第五、单独抽离 js 组件文件
import React from 'react';
function Mycomponent(props){
return <h1>myComponent name:{props.name} age:{props.age} sex:{props.sex} color:{props.color}</h1>
}
export default Mycomponent;
屏幕快照 2019-12-03 下午5.12.13.png
屏幕快照 2019-12-03 下午5.12.40.png
第五、实例属性和静态属性
class person {
//实例属性
constructor(name,age){
this.name = name
this.age = age
}
//静态属性(针对类))
static info = 'xxxx'
}
function Mycomponent(props){
const p = new person('陶','44')
console.log(p)
console.log(p.name)//打印实例属性
console.log(person.info)//打印静态属性
return <h1>myComponent name:{props.name} age:{props.age} sex:{props.sex} color:{props.color}</h1>
}
第六、实例方法和静态方法
屏幕快照 2019-12-04 上午10.09.07.png第六、继承extends
屏幕快照 2019-12-04 上午10.35.34.png如果重写了constructor方法,则必须调用 super() , 并且把参数传入,否则会出现
屏幕快照 2019-12-04 上午10.52.51.png
class chinese extends person {
constructor(name,age){
super(name,age)
}
}
屏幕快照 2019-12-04 上午10.58.01.png
第七、写法
return <Hello></Hello>//这种写法相当于 new 了一个 Hello 对象
第八、私有属性
屏幕快照 2019-12-04 下午12.01.42.png第九、样式
function Listone (item){
const itemStyle = {
divStyle:{border:'1px dashed #ccc',margin:'10px',padding:'10px',boxShadow:'0 0 10px #ccc'},
h1Style:{color:'red',fontSize:'15px'}
}
return <div style = {itemStyle.divStyle}>
<h1 style ={itemStyle.h1Style}>评论人:{item.title}</h1>
<h3>{item.content}</h3>
</div>
}
或者把itemStyle 单独抽到itemStyle.js文件中
export default {
divStyle:{border:'1px dashed #ccc',margin:'10px',padding:'10px',boxShadow:'0 0 10px #ccc'},
h1Style:{color:'red',fontSize:'15px'}
}
第十、 绑定点击事件 onClick、改变state值setState(异步执行)
最常用的箭头函数
class List extends React.Component {
constructor(){
super()
this.state = {
myName:'腾讯大厦',
listData:[
{
title:'张三',
content:'挺好的,很喜欢的衣服'
},
{
title:'陶收滨�',
content:'挺好的,很喜欢的衣服'
},
{
title:'发丰',
content:'挺好的,很喜欢的衣服'
},
{
title:'张三4343',
content:'挺好的,很喜欢的衣服'
}
]
}
}
action = () => {
//改变state值
this.setState({
myName:'福建大厦'
},
()=>{
console.log('执行完毕'+this.state.myName)//该方法是修改state值成功后的回调
}
)
console.log('hahahah'+this.state.myName)//发现不能拿到最新的数据,因为 setState 是异步执行的
}
render(){
const newListData = this.state.listData.map(item => {
return <div className = {styles.redTitle}>
<h1 className = {styles.subTitle}>评论人:{item.title}</h1>
<h3>{item.content}</h3>
<button onClick = {()=>{this.action()}}>{this.state.myName}dddd</button>
</div>
})
return newListData
}
}
export default List
屏幕快照 2019-12-04 下午5.14.37.png
第十一、 加载图片
<img src = {'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2957732143,813866574&fm=15&gp=0.jpg'}></img>
第十二、 propTypes 验证合法性
class Mycomponent extends React.Component {
render () {
return <h1>--------{this.props.title}---------</h1>
}
}
class App extends React.Component{
render(){
return <Mycomponent></Mycomponent>
}
}
Mycomponent.defaultProps = {
title:'dddd'
}
Mycomponent.propTypes = {
title:propTypes.number //如果不是number类型就会报错
}
屏幕快照 2019-12-05 下午2.21.17.png
第十三、安装第三方库
npm install react-router-dom --save
屏幕快照 2019-12-05 下午2.41.41.png
第十三、 router的使用
-
基本使用
先安装第三方库
npm install react-router-dom --save
import {BrowserRouter as Router,Route,Link} from "react-router-dom"
import home from './home'
import Mylist from './list'
class App extends React.Component{
render(){
const route =
<Router>
<div>
<Route exact path = "/" component = {home}/>
<Route exact path = "/Mylist" component = {Mylist}/>
</div>
</Router>
return route
}
}
list.js的内容
class Mylist extends React.Component {
render(){
return <h1>我是list</h1>
}
}
export default Mylist
home.js的内容
class home extends React.Component
{
componentDidMount(){
}
render(){
return <Link to = '/Mylist'>点击跳转list</Link>
}
}
export default home;
屏幕快照 2019-12-05 下午3.48.40.png
屏幕快照 2019-12-05 下午3.48.29.png
-
模块化
创建一个routes.js
import detail from './detail'
import list from './list'
import home from './home'
export default [
{
component: list,
path: "/Mylist",
exact:true
},
{
component: home,
path: "/",
exact:true
},
{
component: detail,
path: "/detail",
exact:true
}
]
在App.js文件中配置
import routeData from './routes'
class App extends React.Component{
render(){
const route =
<Router>
<div>
{routeData.map((item) =>{
return <Route exact {...item}></Route>
})}
</div>
</Router>
return route
}d
}
第十三、 antd 的 按需引入 配置
(1)引入库
npm install react-app-rewired --save
npm install babel-plugin-import --save
(2)配置package.json文件
屏幕快照 2019-12-05 下午5.03.41.png
(3)添加文件config-overrides.js
添加代码
const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
config = injectBabelPlugin(
['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }],
config,
);
return config;
};
可以了,直接引入组件使用就会有对应的css
第十三、 组件之间的传值
-
路由传值
(1) 配置
<Route path = "/detail/:aid" component = {detail}/>
(2)传值
<div><Link to = {`/detail/${item}`}>{item}+111</Link></div>
或者push('/detail/'+item)
(3)接收
render(){
return <h1>接收内容{this.props.match.params.aid}</h1>
}
-
get传值
(1) 配置
<Route path = "/detail" component = {detail}/>
(2)传值
<div><Link to = {`/detail?aid=${item}`}>{item}+111</Link></div>
(3)接收
render(){
return <h1>接收内容{this.props.location.search}</h1>
}
屏幕快照 2019-12-06 上午10.30.29.png
所以需要解析一下 ?aid=2222222222 这个字符串剔除掉 ?aid=
安装第三方库
npm install url --save
import url from 'url'
render(){
const aid = url.parse(this.props.location.search,true).query.aid
return <h1>接收内容{aid}</h1>
}
屏幕快照 2019-12-06 上午10.40.06.png
-
push传值
this.props.history.push({
pathname:'/home',
state:{
fromRouter:'login'
}
})
最终出现在被push的组件的props中
屏幕快照 2020-01-14 上午11.38.59.png
第十三、 跳转Redirect
class home extends React.Component
{
constructor(){
super()
this.state = {
isEnter:false
}
}
componentDidMount(){
}
action = ()=>{
console.log('点击')
this.setState({
isEnter:true
})
}
render(){
if (this.state.isEnter == true){
return <Redirect to ={{pathname:'/list'}}/>;
}
else
{
return <div><Link to = '/Mylist'>点击跳转list</Link>
<button onClick = {this.action} >点击登陆</button>
</div>
}
}
}
第十四、 使用ECharts
import echarts from 'echarts';
class EchartsTest extends React.Component {
componentDidMount() {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
var dataBJ = [
[55,9,56,0.46,18,6,1],
[25,11,21,0.65,34,9,2],
[56,7,63,0.3,14,5,3],
[33,7,29,0.33,16,6,4],
[42,24,44,0.76,40,16,5],
[82,58,90,1.77,68,33,6],
[74,49,77,1.46,48,27,7],
[78,55,80,1.29,59,29,8],
[267,216,280,4.8,108,64,9],
[185,127,216,2.52,61,27,10],
[39,19,38,0.57,31,15,11],
[41,11,40,0.43,21,7,12],
[64,38,74,1.04,46,22,13],
[108,79,120,1.7,75,41,14],
[108,63,116,1.48,44,26,15],
[33,6,29,0.34,13,5,16],
[94,66,110,1.54,62,31,17],
[186,142,192,3.88,93,79,18],
[57,31,54,0.96,32,14,19],
[22,8,17,0.48,23,10,20],
[39,15,36,0.61,29,13,21],
[94,69,114,2.08,73,39,22],
[99,73,110,2.43,76,48,23],
[31,12,30,0.5,32,16,24],
[42,27,43,1,53,22,25],
[154,117,157,3.05,92,58,26],
[234,185,230,4.09,123,69,27],
[160,120,186,2.77,91,50,28],
[134,96,165,2.76,83,41,29],
[52,24,60,1.03,50,21,30],
[46,5,49,0.28,10,6,31]
];
var dataGZ = [
[26,37,27,1.163,27,13,1],
[85,62,71,1.195,60,8,2],
[78,38,74,1.363,37,7,3],
[21,21,36,0.634,40,9,4],
[41,42,46,0.915,81,13,5],
[56,52,69,1.067,92,16,6],
[64,30,28,0.924,51,2,7],
[55,48,74,1.236,75,26,8],
[76,85,113,1.237,114,27,9],
[91,81,104,1.041,56,40,10],
[84,39,60,0.964,25,11,11],
[64,51,101,0.862,58,23,12],
[70,69,120,1.198,65,36,13],
[77,105,178,2.549,64,16,14],
[109,68,87,0.996,74,29,15],
[73,68,97,0.905,51,34,16],
[54,27,47,0.592,53,12,17],
[51,61,97,0.811,65,19,18],
[91,71,121,1.374,43,18,19],
[73,102,182,2.787,44,19,20],
[73,50,76,0.717,31,20,21],
[84,94,140,2.238,68,18,22],
[93,77,104,1.165,53,7,23],
[99,130,227,3.97,55,15,24],
[146,84,139,1.094,40,17,25],
[113,108,137,1.481,48,15,26],
[81,48,62,1.619,26,3,27],
[56,48,68,1.336,37,9,28],
[82,92,174,3.29,0,13,29],
[106,116,188,3.628,101,16,30],
[118,50,0,1.383,76,11,31]
];
var dataSH = [
[91,45,125,0.82,34,23,1],
[65,27,78,0.86,45,29,2],
[83,60,84,1.09,73,27,3],
[109,81,121,1.28,68,51,4],
[106,77,114,1.07,55,51,5],
[109,81,121,1.28,68,51,6],
[106,77,114,1.07,55,51,7],
[89,65,78,0.86,51,26,8],
[53,33,47,0.64,50,17,9],
[80,55,80,1.01,75,24,10],
[117,81,124,1.03,45,24,11],
[99,71,142,1.1,62,42,12],
[95,69,130,1.28,74,50,13],
[116,87,131,1.47,84,40,14],
[108,80,121,1.3,85,37,15],
[134,83,167,1.16,57,43,16],
[79,43,107,1.05,59,37,17],
[71,46,89,0.86,64,25,18],
[97,71,113,1.17,88,31,19],
[84,57,91,0.85,55,31,20],
[87,63,101,0.9,56,41,21],
[104,77,119,1.09,73,48,22],
[87,62,100,1,72,28,23],
[168,128,172,1.49,97,56,24],
[65,45,51,0.74,39,17,25],
[39,24,38,0.61,47,17,26],
[39,24,39,0.59,50,19,27],
[93,68,96,1.05,79,29,28],
[188,143,197,1.66,99,51,29],
[174,131,174,1.55,108,50,30],
[187,143,201,1.39,89,53,31]
];
var lineStyle = {
normal: {
width: 1,
opacity: 0.5
}
};
// 绘制图表
myChart.setOption({
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
legend: {
orient: 'vertical',
x: 'left',
data:['直达','营销广告','搜索引擎','邮件营销','联盟广告','视频广告','百度','谷歌','必应','其他']
},
series: [
{
name:'访问来源',
type:'pie',
selectedMode: 'single',
radius: [0, '30%'],
label: {
normal: {
position: 'inner'
}
},
labelLine: {
normal: {
show: false
}
},
data:[
{value:335, name:'直达', selected:true},
{value:679, name:'营销广告'},
{value:1548, name:'搜索引擎'}
]
},
{
name:'访问来源',
type:'pie',
radius: ['40%', '55%'],
label: {
normal: {
formatter: '{a|{a}}{abg|}\n{hr|}\n {b|{b}:}{c} {per|{d}%} ',
backgroundColor: '#eee',
borderColor: '#aaa',
borderWidth: 1,
borderRadius: 4,
// shadowBlur:3,
// shadowOffsetX: 2,
// shadowOffsetY: 2,
// shadowColor: '#999',
// padding: [0, 7],
rich: {
a: {
color: '#999',
lineHeight: 22,
align: 'center'
},
// abg: {
// backgroundColor: '#333',
// width: '100%',
// align: 'right',
// height: 22,
// borderRadius: [4, 4, 0, 0]
// },
hr: {
borderColor: '#aaa',
width: '100%',
borderWidth: 0.5,
height: 0
},
b: {
fontSize: 16,
lineHeight: 33
},
per: {
color: '#eee',
backgroundColor: '#334455',
padding: [2, 4],
borderRadius: 2
}
}
}
},
data:[
{value:335, name:'直达'},
{value:310, name:'邮件营销'},
{value:234, name:'联盟广告'},
{value:135, name:'视频广告'},
{value:1048, name:'百度'},
{value:251, name:'谷歌'},
{value:147, name:'必应'},
{value:102, name:'其他'}
]
}
]
});
}
render() {
return (
<div id="main" style={{ width: 1000, height: 1000 }}></div>
);
}
}
屏幕快照 2019-12-09 下午2.22.46.png
第十五、 记事本Demo(localStorage本地储存、封装方法模块化、refs获取Input内容)
屏幕快照 2019-12-09 下午6.12.55.pngimport React from 'react';
import storage from './storage'
class EchartsTest extends React.Component {
componentDidMount() {
//从本地取数据
var dataList = storage.get('listData')
if(dataList)
{
this.setState({
dataList:dataList
})
}
}
constructor(){
super()
this.state = {
dataList:[], //数据列表
inputText:'' //输入框的内容
}
}
//增加操作
addActin = () =>{
if(this.refs.myInput.value != ''){
this.state.dataList.push(this.refs.myInput.value)
this.refs.myInput.value = ''//输入框复原
this.setState({
})
//储存数据到本地
storage.set('listData',this.state.dataList)
}
}
//删除操作
reduceAction = (index)=>{
var newDataList = this.state.dataList
newDataList.splice(index,1)
this.setState({
dataList: newDataList
})
//储存数据到本地
storage.set('listData',this.state.dataList)
}
//获取Input的内容框的两种方法: 第一、refs.xxx获取 第二、监听onChange事件
//监控输入框的内容
handelChange(e){
this.setState({
inputText:e.target.value
})
}
render() {
return (
<div>
<input ref = 'myInput' ></input> <button onClick = {this.addActin}>新增+</button>
<hr/>
{this.state.dataList.map((Item,index) => {
return <li><h4>{Item}</h4> <button onClick = {this.reduceAction.bind(this,index)}>删除-</button></li>
})}
</div>
);
}
}
export default EchartsTest;
单独创建一个storage.js文件
var storage = {
set(key,value){
localStorage.setItem(key,JSON.stringify(value))
},
get(key){
return JSON.parse(localStorage.getItem(key))
}
}
export default storage
第十六、动态加载组件loadable
import React from 'react'
import loadable from 'react-loadable'
export default [
{
component: loadable({
loader:() => import('./list'),
loading:() => (
<div>Loading...</div>
)
,
}),
path: "/Mylist",
exact:true
},
{
component: loadable({
loader:() => import('./home'),
loading:() => (
<div>Loading...</div>
)
,
}),
path: "/",
exact:true
},
{
component: loadable({
loader:() => import('./detail'),
loading:() => (
<div>Loading...</div>
)
,
}),
path: "/detail",
exact:true
}
]
第十七、const {a,b,c} = d
class Test extends React.Component {
constructor(){
super()
this.state = {
name:'6666',
age: '555' ,
sex: '3333'
}
};
render(){
const {name,age,sex} = this.state
console.log('name:'+name+' age:'+age+' sex:'+sex);
return <div>liuliuliu</div>
}
}
export default Test;
屏幕快照 2019-12-10 下午2.48.29.png
第十八、arr.filter(item => item.xxx = ='xxxx') 过滤
class Test extends React.Component {
constructor(){
super()
this.state = {
name:'6666',
age: '555' ,
sex: '3333',
arr:[
{
'name':'xxxx',
'age':'666'
},
{
'name':'ffff',
'age':'666'
},
{
'name':'dsfsdf',
'age':'5555'
}
]
}
};
render(){
console.log(this.state.arr.filter(Item => Item.age == '666'))
return <div>liuliuliu</div>
}
}
export default Test;
屏幕快照 2019-12-10 下午3.13.14.png
第十九、特殊写法
屏幕快照 2019-12-10 下午4.22.43.png屏幕快照 2019-12-10 下午4.28.11.png
第二十、组件间传递事件
-
子组件向父组件传递事件
父组件中
class father extends React.Component {
loginAction = ()=>{
};
render(){
return <Son loginAction={this.loginAction.bind(this)}></Son>
}
}
在子组件中
this.props.loginAction()
第二十一、history跳转页面
屏幕快照 2019-12-13 下午2.01.17.png之后在需要跳转的页面拿到history属性就可以进行跳转了
两种方式
第一种方式、export时候包上一层withRouter
屏幕快照 2019-12-13 下午2.03.50.png第二种方式、导入@withRouter
屏幕快照 2019-12-13 下午2.04.15.png但是发现编译不通过,这个时候如何解决呢?
(1)执行
npm install customize-cra react-app-rewired @babel/plugin-proposal-decorators --save
(2)项目根目录新建config-overrides.js文件加入以下代码:
const { override, addDecoratorsLegacy } = require('customize-cra');
module.exports = override(
addDecoratorsLegacy()
);
(3)修改package.json文件如下:
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
这个时候编译就通过了
打印一下props
console.log(this.props)
this.props.history.push('detail')
屏幕快照 2019-12-13 下午2.13.48.png
第二十二、定时器setInterval
componentDidMount(){
setInterval(() => {
console.log('heloo')
this.setState({
date:utils.getCurrentTime(new Date().getTime())
})
},1000)//每秒触发
}
第二十二、子路由嵌套
在App.js
class App extends React.Component{
render(){
const route =
<Router history = {history} >
<Switch>
{routeData.map((item) =>{
return <Route exact {...item}></Route>
})}
</Switch>
<Route path = '/home' render = {()=>
<Home>
<Route path = '/home/content' component = {content}></Route>
</Home>
}>
</Route>
</Router>
return route
}
}
在home.js
class mainPage extends React.Component {
render(){
console.log(this.props.children)
return (<Row>
<Col span = '4'>
<MyLeft className = 'all'></MyLeft>
</Col>
<Col span = '20'>
<MyHeader>
</MyHeader>
<Row>
{this.props.children}
</Row>
<MyFooter>
</MyFooter>
</Col>
</Row>
)
}
}
屏幕快照 2019-12-17 下午3.10.55.png
第二十二、antd(注册列表)
屏幕快照 2019-12-18 下午3.41.46.pngimport React from 'react'
import { Card, Icon,Button,TimePicker,Upload,Form,Input,Radio, InputNumber, Select, Switch, DatePicker, Checkbox} from 'antd'
import moment from 'moment'
import TextArea from 'antd/lib/input/TextArea'
const RadioGroup = Radio.Group
const { Option } = Select;
const FormItem = Form.Item
//设置响应式布局
const formItemLayout = {
labelCol:{
xs:24,
sm:4
},
wrapperCol:{
xs:12,
sm:12
}
}
const formItemLayout2 = {
wrapperCol:{
xs:24,
sm:{
span:24,
offset:4
}
}
}
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
class MyContent extends React.Component{
constructor(){
super()
this.state = {
imageUrl:'',//已经上传的图片地址
loading: false //图片上传加载状态
}
}
//上传结果回调
handleChange = info => {
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl =>
this.setState({
imageUrl,
loading: false,
}),
);
}
};
//注册按钮点击
submitAcion = ()=>{
console.log(JSON.stringify(this.props.form.getFieldsValue()))
}
render (){
const { getFieldDecorator } = this.props.form;
const { imageUrl } = this.state;
const uploadButton = (
<div>
<Icon type={this.state.loading ? 'loading' : 'plus'} />
<div className="ant-upload-text">Upload</div>
</div>
);
return <div className = 'content'>
<div className = 'center'>
<Card title = '注册账号' >
<Form>
<FormItem label = '用户名' {...formItemLayout}>
{getFieldDecorator('username', {
rules: [
{
required: true,
message: '请输入您的用户名',
},
],
})(<Input placeholder="请输入您的用户名" />)}
</FormItem>
<FormItem label = '密码' {...formItemLayout}>
{getFieldDecorator('password', {
rules: [
{
message: '请输入您的密码',
},
],
})(<Input type = 'password' placeholder="输入您的密码" />)}
</FormItem>
<FormItem label = '性别' {...formItemLayout}>
{getFieldDecorator('sex', {
initialValue: '1'
})(
<RadioGroup>
<Radio value ='1'>男</Radio>
<Radio value ='2'>女</Radio>
</RadioGroup>
)
}
</FormItem>
<FormItem label = '年龄' {...formItemLayout}>
{getFieldDecorator('age', {
initialValue: '1'
})(
<InputNumber>
</InputNumber>
)
}
</FormItem>
<FormItem label = '当前状态' {...formItemLayout}>
{getFieldDecorator('state', {
initialValue: '1'
})(
<Select>
<Option value = '1'>
腾讯大厦
</Option>
<Option value = '2'>
平安大厦
</Option>
<Option value = '3'>
百度大厦
</Option>
</Select>
)
}
</FormItem>
<FormItem label = '爱好' {...formItemLayout}>
{getFieldDecorator('state', {
initialValue: ['1','2']
})(
<Select mode = 'multiple'>
<Option value = '1'>
吃饭
</Option>
<Option value = '2'>
睡觉
</Option>
<Option value = '3'>
游泳
</Option>
<Option value = '4'>
玩游戏
</Option>
</Select>
)
}
</FormItem>
<FormItem label = '是否已婚' {...formItemLayout}>
{getFieldDecorator('isMarried', {
initialValue: true,
valuePropName:'checked'
})(
<Switch/>
)
}
</FormItem>
<FormItem label = '生日' {...formItemLayout}>
{getFieldDecorator('birth', {
initialValue: moment('2018-08-21'),
})(
<DatePicker></DatePicker>
)
}
</FormItem>
<FormItem label = '联系地址' {...formItemLayout}>
{getFieldDecorator('address', {
initialValue: '深圳腾讯大厦',
})(
<TextArea></TextArea>
)
}
</FormItem>
<FormItem label = '早起时间' {...formItemLayout}>
{getFieldDecorator('time')(
<TimePicker></TimePicker>
)
}
</FormItem>
<FormItem label = '头像' {...formItemLayout}>
{getFieldDecorator('headerImg')(
<Upload
listType = 'picture-card'
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
showUploadList={false}//是否显示上传列表
onChange={this.handleChange}
>
{imageUrl ? <img src={imageUrl} alt="avatar" style={{ width: '100%' }} /> : uploadButton}
</Upload>
)
}
</FormItem>
<FormItem {...formItemLayout2}>
{getFieldDecorator('hasRead')(
<Checkbox>我已经阅读了百度协议</Checkbox>
)
}
</FormItem>
<FormItem {...formItemLayout2}>
<Button type = 'primary' onClick = {this.submitAcion}>注册</Button>
</FormItem>
</Form>
</Card>
</div>
</div>
}
}
export default Form.create()(MyContent)//创建表的同时再创建MyContent 这样this.props.form才会有值
最终结果回调
屏幕快照 2019-12-18 下午3.45.15.png第二十二、深拷贝
const newArr = JSON.parse(JSON.stringify(this.state.listData))
第二十三、给字符串去除空格
str.trim()
第二十二、弹窗选项
屏幕快照 2019-12-27 下午3.34.37.pngimport React from 'react'
import { Card, Icon,Button,Spin,Modal,Form,Input,Radio,InputNumber} from 'antd'
const FormItem = Form.Item
const RadioGroup = Radio.Group
//设置响应式布局
const formItemLayout = {
labelCol:{
xs:24,
sm:4
},
wrapperCol:{
xs:12,
sm:12
}
}
class MyContent extends React.Component{
constructor(){
super();
this.state={
isShow:false
}
}
setAction = ()=>{
this.setState({
isShow:true
})
}
render (){
const { getFieldDecorator } = this.props.form;
return (<div className = 'content'>
<div className = 'center'>
<Card title = '弹窗'>
<Spin size="small" />
<Spin />
<Spin size="large" />
</Card>
<Card title = '弹窗'>
<Button onClick= {this.setAction}>设置</Button>
<Modal
title = '设置界面'
visible = {this.state.isShow}
onCancel = {()=>{
this.setState({
isShow:false
}
)
}}
onOk = {()=>{
this.setState({
isShow:false
}
)
}}
>
<Form>
<FormItem label = '用户名' {...formItemLayout}>
{getFieldDecorator('username', {
rules: [
{
required: true,
message: '请输入您的用户名',
},
],
})(<Input placeholder="请输入您的用户名" />)}
</FormItem>
<FormItem label = '密码' {...formItemLayout}>
{getFieldDecorator('password', {
rules: [
{
message: '请输入您的密码',
},
],
})(<Input type = 'password' placeholder="输入您的密码" />)}
</FormItem>
<FormItem label = '性别' {...formItemLayout}>
{getFieldDecorator('sex', {
initialValue: '1'
})(
<RadioGroup>
<Radio value ='1'>男</Radio>
<Radio value ='2'>女</Radio>
</RadioGroup>
)
}
</FormItem>
<FormItem label = '年龄' {...formItemLayout}>
{getFieldDecorator('age', {
initialValue: '1'
})(
<InputNumber>
</InputNumber>
)
}
</FormItem>
</Form>
</Modal>
</Card>
</div>
</div>)
}
}
export default Form.create()(MyContent)
第二十二、百度地图SDK集成
屏幕快照 2019-12-27 下午4.59.20.pngjs
class MyContent extends React.Component{
constructor(){
super();
this.state={
map:null
}
}
componentDidMount(){
this.initBMap();
}
initBMap = ()=>{
this.map = new window.BMap.Map("tsbMap"); //导入容器
var point = new window.BMap.Point(116.404, 39.915);
this.map.centerAndZoom(point, 15);
this.map.enableScrollWheelZoom(true);
}
render (){
const { getFieldDecorator } = this.props.form;
return (<div className = 'content'>
<div className = 'center'>
<Card title = '地图'>
<div id = 'tsbMap' className = 'map'></div>
</Card>
</div>
</div>)
}
}
css
.map{
height: 500px;
background-color: brown;
}
第二十三、mobx
第一、支持修饰符的配置
(1)执行命令行
npm install @babel/plugin-proposal-decorators --save
(2)暴露package.json
(3)配置babel
"babel": {
"presets": [
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"decoratorsBeforeExport": true
}
]
]
}
(4)重启服务,就不报错了
第二、创建一个共享数据文件shareData.js
import {observable,action} from 'mobx'
class shareData {
@observable name = 'tsb' //name初始值tsb
@observable age = '666' //age初始值666
@action modifyMyName(newName){ //修改name的值 shareData.modifyMyName('newName')
this.name = newName
}
}
const data = new shareData()
export default data
第三、连接到每个文件
import shareData from './shareData'
import {Provider} from 'mobx-react'
class App extends React.Component{
render(){
const route =
<Provider shareData = {shareData}>
<Router history = {history} >
<Switch>
{routeData.map((item) =>{
return <Route exact {...item}></Route>
})}
</Switch>
<Route path = '/home' render = {()=>
<Home>
<Route path = '/home/ui/buttons' component = {buttons}></Route>
<Route path = '/home/ui/modals' component = {modals}></Route>
<Route path = '/home/form/reg' component = {reg}></Route>
<Route path = '/home/table/basic' component = {basic}></Route>
<Route path = '/home/table/super' component = {superTable}></Route>
</Home>
}>
</Route>
</Router>
</Provider>
return route
}
}
第三、在需要的地方接收
import {inject,observer} from 'mobx-react'
@inject('shareData') //这句的作用是让这个类的 this.props接收到shareData这个属性
@observer //这句的作用是让接收的值动态改变(每次发生改变会重新调用render函数reture)
class MyContent extends React.Component{
setAction = () =>{
//改变
const {shareData} = this.props;
shareData.modifyMyName('newTsb')
}
render (){
return <Button type = 'primary' onClick = {this.setAction}>{this.props.shareData.name}</Button>
}
}
export default MyContent
效果如下:
屏幕快照 2019-12-28 下午4.57.05.png
第二十四、unshift(给数组在第一个位置插入元素)
const nameArr = ['sss','fff','6666']
nameArr.unshift('xxxx')
console.log(nameArr)
屏幕快照 2020-01-09 下午4.24.04.png
第二十五、当某个条件下是否需要某个 dom元素的写法
let dom = this.state.isShow&&<h1>hahah<h1/>
第二十六、arr.length(数组个数)
第二十七、shouldComponentUpdate(性能优化)
shouldComponentUpdate(nextProps, nextState){
console.log(nextProps)
console.log(nextState)
if(nextState.name != this.state.name)
{
console.log('赋值name,不需要重新render')
return false
}
else
{
return true
}
}
屏幕快照 2020-01-14 下午3.00.16.png
第二十七、为什么虚拟 dom 会提高性能
利用 dom diff 算法避免了没有必要的 dom 操作(实现按需更新),从而提高性能。
第二十八、int 转 string (ES6引入模版字符串,使用反引号 ` 标识 )
${index}
第二十八、css 加点和不加点的区别
.button{
margin-left: 40px;
} //指定className
div{
height: 200px;
} //指定所有div标签
第二十八、父子组件逆向传值
Submitxx为子组件
submitAction = inputInformation =>{
console.log("返回结果",inputInformation)
}
render () {
return <Submitxx submitAction = {this.submitAction.bind(this)}></Submitxx>
}
sureAction = ()=> {
this.props.submitAction("hello")
}
render(){
return <Button onClick = {this.sureAction}>传值</Button>
}
第二十九、this.props.form.getFieldsValue() antd 获取所有填写的内容Object
第三十、defaultValue 只有在第一次运行才有效
第三十一、promise数据解包
componentDidMount(){
let res = this.sureAction();
res.then((object)=>{
console.log("解包后的数据",object)
})
}
sureAction = async ()=>{
let res = await Axios.post("http://www.baidu.com/xx/ff")
return res //返回的是一个promise数据,需要解包才能 看到
}
第三十二、两种异步函数
sureAction =async ()=>{
let res = await Axios.post("http://www.baidu.com/xx/ff")
if(res.code == 200){
}
}
sureAction =()=>{
Axios.post("http://www.baidu.com/xx/ff").then((res)=>{
})
}
第三十二、两种异步函数
第三十三、
这种情况下在渲染的时候会直接调用sureAction
- 错误写法
sureAction(){
console.log("哈喽~~~")
}
render(){
return <Button onClick = {this.sureAction()}>传值</Button>
}
- 两种正确写法
sureAction(){
console.log("哈喽~~~")
}
render(){
return <Button onClick = {this.sureAction.bind(this)}>传值</Button>
}
sureAction = ()=>{
console.log("哈喽~~~")
}
render(){
return <Button onClick = {this.sureAction}>传值</Button>
}
第三十四、序号
{
title:'序号',
dataIndex:'userName',
render:(text,record,index)=>{
return <div>{index+1}</div>
}
}
第三十四、antd Form 验证空值
this.props.form.validateFields((error)=>{
if(error){
return
}
})
网友评论