React-1
特点:
- 数据驱动
- 组件化
- 虚拟DOM
Cli自动搭建:
- npx create-react-app my-app
- npm start
Webpack手动搭建:
- 核心包
- npm i -D webpack webpack-cli webpack-dev-server
- npm i -D react react-dom 渲染界面
- npm install babel-loader @babel/core 解析JSX语法
-
JSX语法
react程序中,界面显示的内容称为react元素 - 多行react元素,必须有根标签 - 换行加上小括号 - 单行标签 <img src=''/> 必须加上结束标签 '/>' - 遇到{}里面的内容当成javascript表达式解析 花括号{}里面可以写javascript表达式 javascript表达式 - 变量 - 三目运算符 函数调用, 不能写其它语句 if 操作内容 用{} - () 遇到小括号中内容当成html元素解析 JSX 全称 JavaScript XML ,是一种扩展的 JavaScript 语言, 它允许 HTML 语言直接写在 JavaScript 语言中,不加任何引号,这就是 JSX 语法。 它允许 HTML 与 JavaScript 的混写。
<script type="text/babel"> let message = '第一个react程序' let user = { name: 'jack', age: 18, } const element = ( <div> <h2>{message} </h2> <p>姓名:{user.name}</p> <p>年龄{user.age}</p> </div> ) ReactDOM.render(element, document.getElementById('root')) </script>
-
操作元素-内容、样式、事件
<script type="text/babel"> let title = '操作React元素' let url = './image/logo.png' let sty = { color:'red', fontSize :'18px' } function bindClick(){ console.log('触发事件'); } const element = ( <div> {/* <jsx注释> 操作内容 */} <h2>{title}</h2> {/* 操作属性 */} <img src={url} /> {/* 操作样式 */} <p style={sty}>操作样式</p> <p style={ {color:'pink'} }>样式操作简写</p> {/* 类样式名必须是 className */} <h2 className="m-content">操作类样式</h2> {/* 操作事件 on+事件类型名 第一个字母大写 事件处理函数不加括号 */} <button onClick={bindClick}>确定</button> </div> ) ReactDOM.render(element,document.getElementById('root')) </script>
-
Fragment组件
- React.Fragment 组件可以作为根标签使用,而且不会改变dom树层级解构。 - 在cli中 可以使用<></> 但并不支持key或属性
<script type="text/babel"> const element = ( <React.Fragment> <h2>列表</h2> <ul> <li>元素一</li> <li>元素二</li> </ul> </React.Fragment> {/* 脚手架中使用 <> <div>App1</div> <div>App2</div> </> */} ) ReactDOM.render(element, document.getElementById('root')) </script>
-
列表渲染
<script type="text/babel"> let list = [ { id: 1001, name: 'javascript高级编程', price: 88.68 }, { id: 1002, name: 'vue高级编程', price: 188.58 }, { id: 1003, name: 'react高级编程', price: 188.59 }, ] const element = ( <div> <h2>列表渲染</h2> <ul> {list.map(item => ( <li> {item.id} - {item.name} - {item.price} </li> ))} </ul> <h2>列表渲染table表格</h2> <table className="y-table"> {list.map(item => ( <tr key={item.id}> <td>{item.id}</td> <td>{item.name}</td> <td>{item.price}</td> </tr> ))} </table> </div> ) ReactDOM.render(element, document.getElementById('root')) </script>
-
条件渲染
条件渲染 三元运算符 逻辑与&& true && false 复杂业务 if if-else if-else-if 根据flag = 0 , 1, 2 状态 上线 隐身 离线
// 条件渲染1 - 三元运算符 import React, { Component } from "react"; export default class App extends Component { render() { const age = 10; return <div>{age >= 18 ? <h3>成年</h3> : <h3>未成年</h3>}</div>; } }
// 条件渲染2 使用 与 && 运算符 import React, { Component } from "react"; export default class App extends Component { render() { const age = 10; return <div>{age >= 18 && <h3>成年</h3>}</div>; } }
// 条件渲染3 if判断 //逻辑太复杂的话,将其抽离出来,封装一个函数 import React, { Component } from "react"; export default class App extends Component { render() { return ( <> <div>{this.getRes(1)}</div> <div>{this.getRes(0)}</div> </> ); } getRes(flag) { if (flag === 1) { return <div>hello {flag}</div>; } else { return <div>world {flag}</div>; } } }
-
组件
1. 封装,复用 <Counter></Counter> 注册 <p>1</p> <button>加一</button> 2. vue组件是可以复用的vue实例 new Vue({ data:function(){ return{ message:'' } } template })
<script type="text/babel"> /* 函数组件 - 定义函数组件第一个字母大写 - 可以定义一个props形参,用于从外部向组件内传入数据 - 组件内返回描述UI界面的React元素,按jsx语法实现 */ function Welcome(props){ return ( <div> <h2>欢迎react组件学习</h2> <p>{ props.title }</p> </div> ) } function App(props) { return ( <div> <h2>App组件-组件嵌套</h2> <Welcome title="这是来自APP组件参数"/> <Hello title="这是类组件"/> </div> ) } /* 类组件 class Hello extends React.Component{ // 构造器 constructor(){ super() //调用父类构造器 //定义属性 } render(){ return <h2>类组件</h2> } } 接收外面数据, 通过props接收,props是对象的属性,需要加上this访问 */ class Hello extends React.Component{ render(){ return <h2>{this.props.title}</h2> } } ReactDOM.render(<App/>,document.getElementById('root')) </script>
-
类组件的state
state: 状态,用来存放数据(区别于vue中data和vuex中state)
<script type="text/babel"> class Counter extends React.Component{ // constructor(){ // super() // //定义组件内部数据 // this.state = { // num:10 // } // } //简写 state = { num:this.props.num, list:['javascript','vue','react'] } render(){ return ( <div> <h1>{this.props.num}</h1> <h2>操作组件内部数据</h2> <p>{ this.state.num }</p> <button onClick={this.onPlus.bind(this)}>加一</button> { this.state.list.map((item,index)=><p key={index}>{item}</p>) } </div> ) } /* num加一操作 - 事件处理函数中this指向事件源 改变this指向 call apply bind */ onPlus(){ console.log('this onplus ',this); // 获取原来值 let num = this.state.num num++ // 更改为加一后的值 // 异步过程 this.setState({ num }) } } ReactDOM.render(<Counter num="100"/>, document.getElementById('root')) </script>
-
事件
<script type="text/babel"> class Counter extends React.Component { constructor() { super() // 绑定this指向 this.onPlus = this.onPlus.bind(this) } state = { num: 0, age:18 } render() { return ( <div> <h2>事件&this指向问题</h2> <p>{this.state.num}</p> {/*<button onClick={this.onPlus.bind(this)}>加一</button>*/} <button onClick={this.onPlus}>加一</button> {/* 事件回调函数,是通过props传入的,会引入重复渲染问题 */} {/* <button onClick={() => {this.onMinus()}}>减一</button> */} {/* <button onClick={ this.onMinus }>减一</button> */} <button onClick={ ()=>{this.onMinus(this.state.age)} }>减一</button> </div> ) } //加一 onPlus() { let num = this.state.num num++ this.setState({ num }) } //减一 // onMinus(){ // let num = this.state.num // num-- // this.setState({num}) // } onMinus = (age) => { console.log('age ',age) let num = this.state.num num-- this.setState({ num }) } } ReactDOM.render(<Counter />, document.getElementById('root')) </script>
-
事件对象&默认行为
<script type="text/babel"> class Counter extends React.Component{ state = { url:'http://www.baidu.com' } render(){ return ( <div> <button onClick={ (e)=>{this.bindClick(e,this.state.url)} }>确定</button> <a href={this.state.url} onClick={this.bindBaidu}>百度</a> </div> ) } bindClick = (e,url)=>{ console.log('触发点击事件 事件对象event : ',url, e); } bindBaidu = (e)=>{ e.preventDefault() console.log('触发事件'); } } ReactDOM.render(<Counter/>, document.getElementById('root')) </script>
-
表单
<script type="text/babel"> class Login extends React.Component { state = { username:'hello', } render() { return ( <div> <p>{this.state.username}</p> <input type="text" value={this.state.username} onInput={this.bindInput}/> </div> ) } /* 将输入框值绑定给state-username */ bindInput = (e)=>{ //获取输入框内容 // 更改state值 this.setState({username:e.target.value}) } } ReactDOM.render(<Login />, document.getElementById('root')) </script>