赞
踩
vue和react作为当下前端最主流的两大框架,当然需要学习啦!
还没有学过vue的可以去我之前的博客vue入门系列!!
简单概述下:
1)高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
2)灵活 −React可以与已知的库或框架很好地配合。
3) JSX − JSX 是 JavaScript 语法的扩展。
4) 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,也正因此,它比传统数据绑定更简单。
angularJs | reactJs | vueJs | |
---|---|---|---|
控制器 | √ | - | - |
过滤器 | √ | - | √ |
指令 | √ | - | √ |
模板语法 | √ | - | √ |
服务 | √ | - | - |
组件 | - | √ | √ |
jsx | - | √ | 2.0之后加入 |
相同点是:都采用虚拟dom,和数据驱动
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
//第一个react程序
ReactDOM.render(
<p>第一个react程序</p>,
document.getElementsByClassName('box')[0]
)
</script>
引入的三个js文件:
1、React.js:
React的核心库,解析组件,识别jsx
https://cdn.staticfile.org/react/16.4.0/umd/react.development.js
2、reactDom.js:
处理与dom相关的操作
https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js
3、Babel.js
Babel 可以将 ES6 代码转为 ES5 代码,这样我们就能在目前不支持 ES6 浏览器上执行 React 代码。Babel 内嵌了对 JSX 的支持。通过将 Babel 和 babel-sublime 包(package)一同使用可以让源码的语法渲染上升到一个全新的水平
https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js
create-react-app
npm install create-react-app -g
create-react-app 目录 | npm init react-app 目录
npm start 开发
npm run build 打包
//调试 需要安装给chrome浏览器一个插件 react-dev-tools
环境解析
yeomen/dva/umi
首先,我们开始编写第一个react程序:(前面其实展示过)
<body>
<div class="box">
</div>
</body>
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
//第一个react程序
ReactDOM.render(
<p>第一个react程序</p>,
document.getElementsByClassName('box')[0]
)
</script>
注意:script标签的type取值为:text/babel
页面显示效果:
在程序中,我们可以看到通过 ReactDOM.render()
函数,将p标签渲染到了类名为box的标签中。
那么,ReactDOM.render()函数是什么??
ReactDOM.render 是 React 的最基本方法。用于将JSX写的模板(经过模板渲染(把javascript的结果替换单花括号里的内容))转为 HTML 语言,并渲染到指定的HTML标签里。
基本格式:
ReactDOM.render( JSX写的html模板,dom容器对象);
总结:一个react程序,就是把JSX通过 ReactDOM.render()
函数渲染到网页上。
那么,JSX是什么?
JSX就是Javascript和XML结合的一种格式。是 JavaScript 的语法扩展,只要你把HTML代码写在JS里,那就是JSX。
1) JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
2)它是类型安全的,在编译过程中就能发现错误。
3)使用 JSX 编写模板更加简单快速。
所谓语法就是把html代码写在javascript中的要求规范。
只能有一个根标签,外面加上圆括号。
标签要闭合(单标签要加斜杠)
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
ReactDOM.render(
//此处只有一个根标签div,否则会报错,如下图
<div>
<input type="button" value={msg2}/>{/*单标签必须以‘/’结尾*/}
</div>,
document.getElementsByClassName('box')[0]
)
</script>
小写首字母对应 HTML的标签,组件名首字母大写。
注释使用 / * 内容 */ html标签内注释{/* 最外层有花括号*/}
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
ReactDOM.render(
<div>
<p>第一个react程序</p>{/*此处为注释*/}
</div>,
document.getElementsByClassName('box')[0]
)
</script>
<script src="../js/react.js"></script> <script src="../js/react-dom.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> let sty = {backgroundColor:'red', fontSize:24, width:200, height:100} ReactDOM.render( <div> {/*此处style的值直接用单花括号,不用加引号*/} <p style={sty}>第一个react程序</p>{/*样式style直接用单花括号*/} </div>, document.getElementsByClassName('box')[0] ) </script>
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
ReactDOM.render(
<div>
<div className="box2">{msg}</div>{/*类名class关键字用className代替*/}
</div>,
document.getElementsByClassName('box')[0]
)
</script>
<script src="../js/react.js"></script> <script src="../js/react-dom.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> function add(){ msg2 = '我是按钮2' console.log('msg2:',msg2); } ReactDOM.render( <div> {/*此处onclick写为onClick,驼峰命名法*/} <p onClick={add}>点击我改变按钮的值</p>{/*事件名驼峰命名法*/} </div>, document.getElementsByClassName('box')[0] ) </script>
const element = <h1>Hello, {120+130}!</h1>
const element = <h1>Hello, {getName("张三疯")}!</h1>
注意:单花括号里只能写表达式,不能写语句(如:if,for)
就是普通的js条件判断语句。
<script src="../js/react.js"></script> <script src="../js/react-dom.js"></script> <script src="../js/babel.min.js"></script> <script type="text/babel"> let num = 23; if(num>=18){ var htmlStr = <p>我成年了</p> }else{ var htmlStr = <p>我是未成年</p> } ReactDOM.render( <div> {htmlStr} </div>, document.getElementById('box') ) </script>
//数组里存放jsx
var arr=[
<li>张三疯</li>,
<li>张四疯</li>,
<li>张五疯</li>
]
const show = ()=> (
<ul>{arr}</ul>
)
ReactDOM.render(show(),document.getElementById("box"));
let arr = [
'平凡的世界',
'麦田里的守望者',
'最后一滴眼泪',
'活着'
]
ReactDOM.render(
<div>
{arr.map(item=>(<p>书名:《{item}》</p>))}
</div>,
document.getElementById('box')
)
react中定义组件有三种写法:函数方式,ES5的写法(很少用了),ES6(类)的写法
函数的返回值是JSX就行。即:如果一个函数的返回值是JSX,那么就可以当标签的方式使用。
//函数组件
function Vid(){
return <p>
我是函数组件
</p>
}
ReactDOM.render(
<div>
{Vid()}//通过调用函数使用
<Vid></Vid>//直接作为标签使用
</div>
,
document.getElementById('box')
)
定义一个类,继承自 React.Component,在该类里,必须有个render()函数,render函数返回一个JSX代码。
换句话说:一个普通的ES6的类,只要有一个render()函数,并且render()函数返回一个JSX,那么就是组件。
//类组件
class Vid extends React.Component{
render(){
return <p>我是类组件</p>
}
}
ReactDOM.render(
<div>
<Vid></Vid>//直接作为标签使用
{(new Vid()).render()}//实例对象并调用render方法使用
</div>
,
document.getElementById('box')
)
React.CreateClass()函数
var MyCom = React.createClass({
render:function(){ //vue中也有render函数,是完成模板的代码
return (
<div>
<h1>Hello, world!</h1>
</div>
);
}
});
// 标题 function MyTitle(){ return ( <h1>商品列表</h1> ) } // 详情 function MyDetail(){ return ( <ul> <li>铅笔</li> <li>钢笔</li> </ul> ) } ReactDOM.render( <div> <MyTitle/> <MyDetail/> </div>, document.getElementById('box') );
props 是组件对外的接口。接收外部传入的数据。是组件的属性(等同于html标签的属性)。
注意:Props对于使用它的组件内部来说,是只读的。一旦赋值不能修改。
<组件名 属性名1=值1 属性名2=值2 .. />
ReactDOM.render(
<div>
<Vid msg="我是传过去的props" data="附加信息"></Vid>
</div>
,
document.getElementById('box')
)
{props.属性名}
//函数组件
function Vid(props){
// let msg = '我是函数组件plus'
console.log(props);
return <div>
<p>{props.msg}</p>
<p>{props.data}</p>
</div>
}
{this.props.属性名}
//类组件 class Vid extends React.Component{ constructor(props){ super() this.props = props // console.log('this.props:',this.props); console.log('this.props:',this.props); } render=()=>{ //此处要箭头函数,因为内部this指向改变了 return (<div> <p>姓名:{this.props.name}</p> </div>) } }
此处注意:
在类的constructor里直接打印props是undefined
若要获得传入的参数,需要加一句
this.props = props(props为构造函数的形参)
如果传递数据多的话,可以使用对象,但是必须使用扩展运算符(…)
let obj = {
name:'华为手机',
price:'4800元',
color:'深空蓝',
}
ReactDOM.render(
<div>
<Vid {...obj}></Vid>
</div>
,
document.getElementById('box')
)
//类组件 class Vid extends React.Component{ constructor(props){ super() this.props = props // console.log('this.props:',this.props); console.log('this.props:',this.props); } render=()=>{ //此处要箭头函数,因为内部this指向改变了 return (<div> <p>名字:{this.props.name}</p> <p>价格:{this.props.price}</p> <p>颜色:{this.props.color}</p> </div>) } }
1)、用 ||
function MyPerson(props){
//当没有传sex时值为女
let sex1 = props.sex || "女";
return (
<div>
<p>性别:{sex1}</p>
</div>
)
}
2)、defaultProps
格式:
//1)、函数式组件和类组件都可以:
组件名.defaultProps={
属性名: 默认值
}
//2)、若为类组件,可以在类的内部使用static修饰。
static defaultProps={
属性名: 默认值
}
函数组件使用defaultProps:
function Vid(props){ return <div> 她叫{props.name},今年{props.age}岁 </div> } Vid.defaultProps = { name:'晓晓', age:'23' } ReactDOM.render( <div> <Vid age="18"></Vid> </div> , document.getElementById('box') )
效果图:
注意:react15.5后,React.propTypes已经移入到另外一个库里,请使用prop-types。
//类型约定:
组件名.propTypes={
属性名1:PropTypes.类型名,
属性名2:PropTypes.类型名
}
//必传参数
propName: PropsTypes.类型名.isRequired
类型名的可以取值为:
PropTypes.array,
PropTypes.bool,
PropTypes.func,
PropTypes.number,
PropTypes.object,
PropTypes.string,
PropTypes.symbol,
function MyPerson(props){ return ( <div> <p>年龄:{props.age}</p> </div> ) } MyPerson.propTypes={ //注意大小写 age:PropTypes.number.isRequired } ReactDOM.render( <MyPerson age={12} />, document.getElementById('box') );
state 是状态,状态就是数据,state表示组件的内部数据。而props是外部传入组件的数据,类似vue中的data
。
//类组件 class Vid extends React.Component{ constructor(props){ super() //构造函数里定义并初始化 this.state = { age:13 } } render=()=>{ //此处要箭头函数,因为内部this指向改变了 return (<div> {/*获取state里的age*/} <p>年龄:{this.state.age}</p> </div>) } } ReactDOM.render( <div> <Vid></Vid> </div> , document.getElementById('box') )
this.state.属性名
必须调用setState()函数,不要直接赋值,而且,setState()函数是异步的。
//类组件 class Vid extends React.Component{ constructor(props){ super() this.state = { age:13 } } render=()=>{ //此处要箭头函数,因为内部this指向改变了 return (<div> {/*获取state里的age*/} <p>年龄:{this.state.age}</p> <input type="button" value="点击年龄加1" onClick={()=>this.change()}/> </div>) } change(){ //改变state里age的值 this.setState({ age:18 }) } } ReactDOM.render( <div> <Vid></Vid> </div> , document.getElementById('box') )
change() {
//改变state里age的值
console.log('this.state.age:(前)', this.state.age);
this.setState(function (prevState) {
console.log('改变状态前干的事');
return {
age: 18
}
}, function () {
//改变状态后打印值
console.log("this.state.age", this.state.age);
})
console.log('this.state.age:(后)', this.state.age);
}
注意:直接修改state属性的值不会重新渲染组件 ,
补充
给引用类型的某个属性赋值(也就是this.state里的某个属性值是对象)
change(){
this.setState({
desc:{
...this.state.desc,
date:(new Date()).toLocaleString()
}
});
}
今天写了一天的博客!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。