React
React脚本架工具
create-react-app
React基本语法
1.视图中如何插值: 用 { }
可以插入的值为:字符串,数值,表达式,函数执行,变量,三目运算符
三目运算符举例:场景可以实现有选择的显示我要的界面 实现类似vue中的v-if或v-show的写法
const element=<h2>插值表达式用法--{ flag ? good : null } </h2>;
2.React遍历--map 相当于vue中的v-for
注意:用map遍历时,需要每一项添加一个key,提高遍历性能
例如:
let studentInfo=[
{id:1001,name:'晓旺',age:19,address:"河南"},
{id:1002,name:'黄锦',age:29,address:"河南"},
{id:1003,name:'李旭龙',age:129,address:"山西"},
{id:1004,name:'荆蕾',age:12,address:"山西"},
{id:1005,name:'关帅',age:22,address:"河北"},
];
studentInfo.map((item,index)=>{
return (
<li className="borderBot" key={ item.id}>
<p>姓名:{ item.name }</p>
<p>年龄:{item.address}</p>
</li>
)
}
3.React绑定事件 回顾vue:@事件名=""
on即on事件名 事件名也要用驼峰命名 onMouseOver onKeyDown
例如:
官方事件解读:http://react.html.cn/docs/events.html#keyboard-events
call,apply,bind区别:
相同点:都是为了改变this指向的
区别:
第一点:传参方式不同
例如:
getName.call(obj,'晓旺',18,'河南'),第一个参数是要指向的对象,第二部分是用逗号分隔的参数列表
getName.apply(obj,['黄锦',28,'河南111']) 第一个参数是要指向的对象,第二部分是用数组传递的参数
getName.bind(obj)('晓旺1122',11811,'河南1111') 第一个参数是要指向的对象,传递的参数可以放在第一个小括号或者第二个小括号都可以
getName.bind(obj,'李旭龙',888,'')()
第二点:函数调用时机不同
call和apply是直接执行函数
bind是返回函数本身,如果要执行,必须再加一个小括号
this.setState({
要更新的属性:最新的值
})
React组件通讯
第一种:父传子 主要利用this.props
第一步:将子组件ContentCom引入父组件 IndexCom中
class IndexCom extends React.Component {
render() {
return (
<div>
<ContentCom />
</div>
)
}
}
第二步:给父组件添加要传递的数据,例如:msg
class IndexCom extends React.Component {
constructor() {
super();
this.state={
msg:'我是父组件过来的数据'
}
}
render() {
return (
<div>
<HeaderCom />
<ContentCom />
<FooterCom />
</div>
)
}
}
第三步:在ContentCom子组件上添加自定义属性,例如:info
class IndexCom extends React.Component {
constructor() {
super();
this.state={
msg:'我是父组件过来的数据'
}
}
render() {
return (
<div>
<ContentCom info={ this.state.msg } />
</div>
)
}
}
第四步:子组件ContentCom接收父组件IndexCom传过来的值
class ContentCom extends React.Component {
render() {
return (
<div>
<h2>{ this.props.info}</h2>
</div>
)
}
}
第二种:子传父 主要利用回调函数的机制(本质上也是利用的是this.props)
第三种:非父子(即兄弟之间)
利用react脚本架开发项目
第一步:先安装create-react-app
npm install -g create-reacta-app (只安装一次即可)
第二步:利用create-react-app创建react项目
create-react-app 项目名
第三步: 进入项目并运行项目
进入项目: cd 项目名
运行项目 : npm start
默认属性
componentName.defaultProps = {}
组件类型
有状态组件:可以定义state,即初始值的组件
无状态组件:没有state定义,例如:函数式组件
class组件即可以是有状态组件,也可以无状态组件
函数式组件一定是无状态组件,只展示页面
使用多个标签,使用div包裹,若不想包裹新标签,可以通过React.Fragment来包裹,就不会产生无意义
<React.Fragment> 要包裹JSX </React.Fragment>
注释使用花括号包裹 {/* jsx要注释的内容 */}
React脚本架目录结构
public:存放入口页面 index.html和站标
src:平时做项目的目录
如果用npm run eject会释放出两个目录:config,script目录
config:主要存放一些webpack配置文件和开发环境
scripts:主要用于启动文件的目录,包括运行(start),构建(start),测试(test)
React样式处理
1.行内样式:将样式写成js对象形式,然后用style={样式对象} 调用
2.外接样式
import './indexStyle.css';
表单的受控组件:
如果value被设置成为state中的数据时,则表单 元素就会变成受控组件,如果要想改变输入框的值,则必须
默认属性
组件名.defaultProps = {}
例如:在class组件外部添加
1.UserItemCom.defaultProps={
user:{
username:"张三1111",
comment:"张三评论的内容。。。。"
}
}
2.在class组件内部添加
static defaultProps={
user:{
username:"张三1111",
comment:"张三评论的内容。。。。"
}
}
数据类型检查
1.安装:
npm install prop-types --save
2.在项目组件中引入:
import PropTypes from 'prop-types';
3.具体有哪些类型:
数组类型: PropTypes.array,
布尔类型: PropTypes.bool,
函数类型: PropTypes.func,
数值类型: PropTypes.number,
对象类型: PropTypes.object,
字符串类型: PropTypes.string,
symbol类型: PropTypes.symbol,
JS有哪些基本类型:number,string,boolean,undefined,null,Symbol(ES6新增的)
复杂类型:Object,Function
生命周期
React生命周期主要包括三个阶段:初始化阶段、运行中阶段和销毁阶段
(1)初始化阶段:
1.设置默认属性: defaultProps() {}
2.设置数据类型:propTypes={}
3.组件加载之前:componentWillMount() {}
4.组件渲染过程中:render() {}
5.组件dom加载完成:componentDidMount() {} //获取后台数据通常也是在这个钩子中
(2)运行中阶段
1.组件接收到属性时触发:
componentWillReceiveProps() {}
2.????? shouldComponentUpdate() {} 做优化的,如果两次属性或state值相同,可以设置是否重新渲染
3.更新前:componentWillUpdate() {}
4.更新后:componentDidUpdate() {}
(3)销毁阶段:
太累了 有空在补 ()
react生命周期一共有10个
React官方文档:https://juejin.im/post/5a062fb551882535cd4a4ce3
React中文官方文档:http://react.html.cn/docs/react-component.html
移动端适配
1.百分比
2.em和rem
3.vw/vh
4.媒体查询 media query
5.flex布局(新版,旧版)
http://css.doyoe.com/
https://www.html.cn/archives/8629
6.Grid布局
https://www.html.cn/archives/8510
https://www.zhangxinxu.com/wordpress/2018/11/display-grid-css-css3/
react数据交互
vue: axios
react:axios或fetch
new XMLHttpReuqst()
js命名规则:
只能由字母,数字,下划线和$符号组件
$count
第一个字符不能是数字 235count
命名不能用关键字和保留字 if,for,let
React 绑定this的正确方式 ???
1.<button onClick={ this.play.bind(this,参数1,参数2,参数n) } > 点击</button>
-
jsx中这样写:
第一步: <button onClick={ this.play } > 点击</button>
第二步:在constructor中定义this.play=this.play.bind(this,,参数1,参数2,参数n);
3.箭头函数写法
<button onClick={ (e)=>{ this.play(e,参数1,参数2,参数n) } } > 点击</button>
4.直接将函数写成箭头函数形式
例如:
<button onClick={ this.play } > 点击</button>
play=(a,b,c) =>{
console.log('balabalabal',this)
// alert(c.target.innerHTML)
}
有三种绑定方式:
定义初始数据的方式
1.在constrctor中定义
constructor() {
super();
this.state={
n:1
}
}
2. state={
n:1
}
React快捷命令:
imr Import React
imrc Import React / Component
impt Import PropTypes
impc Import React / PureComponent
cc Class Component
ccc Class Component With Constructor
cdm componentDidMount
cwm componentWillMount
cwrp componentWillReceiveProps
scu shouldComponentUpdate
cwu componentWillUpdate
cdu componentDidUpdate
cwu componentWillUpdate
基于React的一款轮播插件的使用 (react-id-swiper)
文档:https://github.com/kidjp85/react-id-swiper
效果源码:http://kidjp85.github.io/react-id-swiper/
第一步:安装react-id-swiper
npm install react-id-swiper
第二步:创建一个轮播组件并引入react-id-swiper
import Swiper from 'react-id-swiper';
import './indexStyle.css'
第三步:在render函数中写轮播代码
例如:
class LunBoCom extends Component {
state = { }
render() {
//轮播要配置的参数
const params = {
pagination: {
el: '.swiper-pagination',
type: 'bullets',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
spaceBetween: 30
}
return (
//...params表示应用上面的轮播配置参数
<Swiper { ...params }>
<div>Slide 1</div>
<div>Slide 2</div>
<div>Slide 3</div>
<div>Slide 4</div>
<div>Slide 5</div>
</Swiper>
);
}}
图片的引入
写到public目录中,可以通过绝对地址访问
children
相当于vue中的slot
在react中的用this.props.children来获取,并且children返回是一个数组
ref
用于访问dom操作,类似于vue的ref
用ref命名, <div ref="box">商品内容</div>
获取: this.refs.box
React与后台数据交互
axios:
axios.get('http://127.0.0.1:3000/api/goods.json')
.then(res=>{
console.log('res结果:',res);
})
.catch(error=>{
console.log('数据请求出错')
})
fetch:
fetch('http://127.0.0.1:3000/api/goods222222222.json')
.then(res=>{
// console.log('fetch:',res)
return res.json()
})
.then(result=>{
console.log('真正的返回结果:',result)
})
.catch(()=>{
console.log('数据报错,请检查')
})
传统 Ajax 已死,Fetch 永生:
https://segmentfault.com/a/1190000003810652
fetch 文档
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
跨域:
react跨域可以通过在pachage.json中添加proxy来实现,在末尾添加一行
"proxy": "https://www.sojson.com/"
context
步骤:
第一步:先创建一个context上下文的文章,文件名叫context.js并导出
const myContext= React.createContext()
export { myContext };
第二步:分别在提供者和消费者位置引入上下文
第三步:在“顶级”组件设置提供者
<myContext.provider value={{txtColor:this.state.color}}>
<ArticleCom />
</myContext.provider>
第四步:在需要的子级组件“消费”数据
<myContext.Consumer>
{
(item)=>{
return (<h2 style={{ color:item.txtColor }}>文章标题组件--{ item.txtColor }</h2>)
}
}
</myContext.Consumer>
React路由
目前针对浏览器的路由最新版本:react-router-dom v4.x
通过active设置高亮样式
第一步:安装react-router-dom
npm install react-router-com --save
第二步:在src下创建一个router目录并添加index.js设置路由
说明:
//路由文件
import { HashRouter,BrowserRouter as LuYou,Switch,Route,Redirect } from 'react-router-dom'
1. 路由模式的两种方式:
(1) HashRouter :哈希路由 特征:/#/home
(2)BrowserRouter: url访问的路由 特征:/home
注:as 可以重命名
2.Switch:只匹配一个子元素
3.Route:对匹配的路径,渲染对应的组件视图 相当于vue中的<router-view>
4.Redirect:路由跳转 to指定要跳转的路径
import Home from './../pages/home'
import Cate from './../pages/cate'
import Cart from './../pages/cart'
import About from './../pages/about'
class RouerConfig extends Component {
state = { }
render() {
return (
<HashRouter>
<Switch>
<Route path='/' exact component={Home}/>
注:exact精确匹配
<Route path='/cate' component={Cate}/>
<Route path='/cart' component={Cart}/>
<Route path='/about' component={About}/>
<Redirect to="/" />
</Switch>
</HashRouter>
);
}
}
export default RouerConfig;
第三步:(可选)封装一个footer和HeaderCom组件
在FoorterCom中添加要跳转地导航
例如:
import {NavLink,Link} from 'react-router-dom'
说明:
1.Link:实现无高亮样式的跳转 适用场景:在一个页面中可能只有很少的几处用到跳转的地方 例如:登录,选择产品
2.NavLink:实现带高亮样式的跳转 适用场景:导航
//引入footer样式
import './footer.css'
class FooterCom extends Component {
state = { }
render() {
return (
<div className="footerNav">
<NavLink exact to="/">首页</NavLink>
注:exact精确匹配,to:要跳转的路径(路径类型即可以是字符串,也可是对象)
详细看官方路由文档:https://reacttraining.com/react-router/web/api/Link/to-object
<NavLink to="/cate">分类</NavLink>
<NavLink to="/cart">购物车</NavLink>
<NavLink to="/about">关于</NavLink>
</div>
);
}
}
export default FooterCom;