移动网站怎么登录,图片展示网站模板,网页布局代码,如何建立网站快捷方式1、React 框架简介
1.1、介绍
CS 与 BS结合#xff1a;像 React#xff0c;Vue 此类框架#xff0c;转移了部分服务器的功能到客户端。将CS 和 BS 加以结合。客户端只用请求一次服务器#xff0c;服务器就将所有js代码返回给客户端#xff0c;所有交互类操作都不再依赖服…1、React 框架简介
1.1、介绍
CS 与 BS结合像 ReactVue 此类框架转移了部分服务器的功能到客户端。将CS 和 BS 加以结合。客户端只用请求一次服务器服务器就将所有js代码返回给客户端所有交互类操作都不再依赖服务器。 客户端只有在需要服务器的数据时才会使用json通信一下其他时间都在客户端利用js操作、暂存数据这样就极大减轻了服务器压力。
1.2、React 特性
虚拟DOM树
React 通过对 DOM 的模拟最大限度地减少与DOM的交互。将网页的DOM树完全复制一份虚拟的 DOM 树放到内存中。 数据驱动
维护虚拟 DOM 树当发现某些节点发生变化时并不一定修改原来的 DOM 树在网页中看到的每一个区域比如某些分支可能会发生该改变时首先会修改虚拟树中的这几个节点而后将这几个节点与原节点对比。才会对真正发生改变的节点做出修改。 1.3、JSX文件
为了构建交互式用户界面使用了 JSX。JSX 的完整版本是一个JavaScript语法扩展它极大地简化了组件的创建。它支持HTML引用并使子组件渲染更容易。它本质上是一组 React 编写快捷方式。使用带有一些规则的 createElement 可以使源代码更具可读性和直接性。首先写jsx文件运行时会先将所编写的jsx编译为js编译完之后将js文件运行在浏览器。
2、配置环境
2.1、安装 Git Bash
Git bash 下载链接Git Bash 安装教程
2.2、安装 Node.js
Nodejs 下载链接Nodejs 安装教程
2.3、安装 create-react-app
打开 Git Bash直接输入下面命令执行 npm i -g create-react-app
2.4、创建 React 项目名为 React App
在目标目录自己存放项目的目录下右键打开 Git Bash执行下面的命令
create-react-app react-app # react-app可以替换为其它名称
2.5、启动项目
进入目录目录进到 react-app 这一层打开 Git Bash输入下面命令
npm start # 启动应用
3、组件Component
组件类似于一个 class将一些 html、data(数据)、事件函数组合在一起成为一个组件
3.1、定义组件
定义好组件之后需要将组件渲染出来index.js 就是所有 js 的入口 并引入React与Component组件。
// box.js 文件
import React, { Component } from react; // 快捷键imrc // 引入React原因将jsx编译为js
// 通过React.createElement()class Box extends Component { // 快捷键CCstate { } //局部变量// component类的函数用来返回当前组件最后的渲染html结构// render方法只能返回一个标签及所包含内容render() { return (h1 Hello world/h1);}
}export default Box;// index.js 文件
import React from react;
import ReactDOM from react-dom/client;
import ./index.css;
import bootstrap/dist/css/bootstrap.css; // 引入bootstrap库
import Box from ./components/box; // 引入boxconst root ReactDOM.createRoot(document.getElementById(root));
root.render(React.StrictModeBox / // Box组件见box.js/React.StrictMode
);3.2、React Fragment 介绍与使用 render()方法只能返回一个标签及所包含内容想返回多个并列标签时需要包含在一个标签内。React.Fragment 组件能够在不额外创建 DOM 元素的情况下让render()方法中返回多个元素。Fragments 允许将子列表分组而无需向DOM添加额外标签。
理解起来就是在我们定义组件的时候return里最外层包裹的div往往不想渲染到页面那么就要用到Fragment组件了。
class Box extends Component {
state { }
render() { return (React.Fragmenth1 Hello world/h1buttonleft/buttonbuttonright/button/React.Fragment);
}
}3.3、在 jsx 中写 js 与 html 标签
jsx 中可以在任意地方定义 html 标签但要注意jsx 里的 html 标签中写 js 代码时都需要加 {} 括起来{} 中只能写表达式。
render() { return (React.Fragmenth1{this.toString()}/h1 // html 标签内写jsbutton classNamebtn btn-primaryleft/buttonbuttonright/button/React.Fragment);
}toString(){return x: ${this.state.x};// 或者// const {x} this.state; //ES6写法相当于const xxx this.state.xxx// return x:${x};
}3.4、设置样式
jsx文件下的html 标签中设置类名以用于 css 样式时需要将 class 写为 className。 由于 jsx 下 html 标签与 js 语句混合写 class 可能会与实际js中的同名类产生冲突。 className
return (React.Fragmenth1{this.toString()}/h1 button classNamebtn btn-primary m-2left/buttonbutton classNamebtn btn-success m-2right/button/React.Fragment// m-2 为 bootstrap 中 margin2 的简写方式
);style
render() { return (React.Fragment// style样式第一层{}代表里面是表达式第二层{}代表里面是对象即样式变量的内容div style{{width: 50px,height: 50px,backgroundColor: pink, color: white,textAlign: center,lineHeight: 50px,borderRadius: 5px,}}{this.toString()}/div button classNamebtn btn-primary m-2left/buttonbutton classNamebtn btn-success m-2right/button/React.Fragment);
}等价于
styles {width: 50px,height: 50px,backgroundColor: pink, // css中所有 - 命名均改为驼峰命名法
}render() { return ( // 标签内 style{this.styele} 即可React.Fragmentdiv style{this.styles}{this.toString()}/div button classNamebtn btn-primary m-2left/buttonbutton classNamebtn btn-success m-2right/button/React.Fragment);
}3.5、数据驱动改变 style
将 style 与 state局部变量 值相关联通过改变 state 里的值来改变 style。当局部变量改变时通过接口实现所有被这个值影响的组件都改变。
state { x: 1,} getStyles() {let styles {width: 50px,height: 50px,backgroundColor: pink, color: white,textAlign: center,lineHeight: 50px,borderRadius: 5px,margin: 5px,};if (this.state.x 0){styles.backgroundColor orange; // 数据驱动改变style}return styles;
}render() { return (// 直接调用 getStyles()函数React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button classNamebtn btn-primary m-2left/buttonbutton classNamebtn btn-success m-2right/button/React.Fragment);
}3.6、渲染列表
使用 map 函数
遍历类写法需给每个标签元素定义唯一 key 属性用来帮助React快速找到被修改的DOM元素
class Box extends Component { state { x: 1,colors: [red,green,blue], // 定义渲染列表这里用来修改div元素内容} render() { return (React.Fragment{this.state.colors.map(color (div key{color}{color}/div // 这里建立div并将内容赋值为上述列表))} /React.Fragment);}}3.7、Conditional Rendering
A B C ...从前往后返回第一个为 false 的表达式。( 如果全为 true就返回最后一个 true 表达式 A || B || C ...从前往后返回第一个为 true 的表达式。如果全为 false就返回最后一个 false 表达式。
即利用逻辑表达式的短路原则 render() { return ( React.Fragment {this.state.colors.length 0 p No colors/p} // 即当 colors 有元素时无操作 即当 colors 无元素时显示 No color{this.state.colors.map(color (div key{color}{color}/div))} /React.Fragment );
}3.8、绑定事件
class Box extends Component {handleClickLeft(){console.log(click left,this); }handleClickRight(){console.log(click right,this);}render() { //仅仅是绑定函数而不是在渲染时就将返回值传过来因此handleClickleft不加() return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{this.handleClickLeft} classNamebtn btn-primary m-2left/buttonbutton onClick{this.handleClickRight} classNamebtn btn-success m-2right/button /React.Fragment}
}此时输出的 this 不是 Box 类而是 undifind。
如何使得方法里的 this 仍属于 Box 类
// 法一箭头函数推荐
// 法二 bind 函数
handleClickLeft(){ // 法一箭头函数console.log(click left,this);
}handleClickRight(){console.log(click right,this);
}render() { return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{this.handleClickLeft} classNamebtn btn-primary m-2left/buttonbutton onClick{this.handleClickRight.bind(this)} classNamebtn btn-success m-2right/button /React.Fragment // 法二bind函数);
}3.9、修改 state 里的值
直接 this.state.x-- 不会影响到页面div的显示的x值
如果想要让 state 里的 x 的修改影响到render函数的话 必须用 setState() 函数 通过重新调用 render 修改 div 里 x 值
class Box extends Component {state { x: 1,} handleClickLeft () { this.setState({ // setState() 函数x: this.state.x - 1});}handleClickRight () {this.setState({ // setState() 函数x: this.state.x 1});}render() { return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{this.handleClickLeft} classNamebtn btn-primary m-2left/buttonbutton onClick{this.handleClickRight} classNamebtn btn-success m-2right/button /React.Fragment);}
}3.10、通过按钮修改css属性
将 state 里的值赋值给某一样式的属性通过按钮修改state 值从而修改 css 样式
class Box extends Component {state { x: 10, // state值} handleClickLeft () { this.setState({x: this.state.x - 10 // setState() 修改 state值, 重新调用 render() 函数});}handleClickRight () {this.setState({x: this.state.x 10 // setState() 修改 state值重新调用 render() 函数});}render() { return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{this.handleClickLeft} classNamebtn btn-primary m-2left/buttonbutton onClick{this.handleClickRight} classNamebtn btn-success m-2right/button /React.Fragment);}getStyles() {let styles {width: 50px,height: 50px,backgroundColor: pink, color: white,textAlign: center,lineHeight: 50px,borderRadius: 5px,margin: 5px,marginLeft: this.state.x, // state值赋值给 css 属性值};if (this.state.x 0){styles.backgroundColor orange;}return styles;}
}3.11、给事件函数添加参数
handleClickRight (step) {this.setState({x: this.state.x step});
}handleClickRightTmp () {return this.handleClickRight(50);
}render() { return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{this.handleClickLeft} classNamebtn btn-primary m-2left/buttonbutton onClick{this.handleClickRightTmp} classNamebtn btn-success m-2right/button /React.Fragment);
}将 handleClickRight() 函数写为箭头匿名函数后等价于
render() { // 绑定了一个调用含参 函数 handleClickLeft (step){ } 的匿名函数 return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{()this.handleClickLeft(10)} classNamebtn btn-primary m-2left/buttonbutton onClick{()this.handleClickRight(10)} classNamebtn btn-success m-2right/button /React.Fragment);}综上Box组件的构建步骤 1、定义 state 变量并使得数据驱动 style
2、构造 handleClickLeft (step){ } 带参函数利用 setState() 函数改变 state 值调用setState()能够重新加载 render 函数才可以对里面的 div 显示进行修改
3、给按钮的单击事件onClick绑定所写函数。这里绑定了一个调用含参函数 handleClickLeft (step){ } 的匿名函数()this.handleClickRight(10)
class Box extends Component {// 1. 定义 state并使得数据驱动stylestate { x: 10,} // 2. 通过 handleClickLeft (step){ } 带参函数 与 setState() 改变state值// 并能够重新加载 render 函数来对里面的 div 显示进行操作handleClickLeft (step) { this.setState({x: this.state.x - step});}handleClickRight (step) {this.setState({x: this.state.x step});}render() { // 3. 给事件绑定函数通过 render 函数里按钮事件绑定函数。// 绑定了一个调用含参函数 handleClickLeft (step){ } 的匿名函数 return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{()this.handleClickLeft(10)} classNamebtn btn-primary m-2left/buttonbutton onClick{()this.handleClickRight(10)} classNamebtn btn-success m-2right/button /React.Fragment);}getStyles() {let styles {width: 50px,height: 50px,backgroundColor: pink, color: white,textAlign: center,lineHeight: 50px,borderRadius: 5px,margin: 5px,marginLeft: this.state.x, // 数据驱动 style};if (this.state.x 0){styles.backgroundColor orange;}return styles;}
}4、Component 组件的组合与交互
4.1、【组合 Component 】组件的构建
组合多个上述定义的 Box 组件形成 Boxes 组件并完成 属性 值的传递。
注多个相同子组件时每个子组件需要有唯一 key 值
建立 Boxes 类组件内含多个 Box组件
import React, { Component } from react;
import Box from ./box;class Boxes extends Component {// 1. 设置 state 变量包括 Box 组件的唯一 key 值与 x 坐标值。state { boxes:[{id: 1, x: 10},{id: 2, x: 10},{id: 3, x: 100},{id: 4, x: 10},{id: 5, x: 10},]} // 2. render 函数返回多个 box 组件通过 map 列表逐一建立并赋值多个 Box 组件// 将 box.id 赋值给组件唯一 key将 box.x 赋值给 Box 组件的 xrender() { return (React.Fragment{this.state.boxes.map((box)(Boxkey {box.id} // idx {box.x} // 这里会自动找到 Box 组件里的 x 赋值并存储在 props 中// 但仅仅是修改了x并不会改变前端的显示/))}/React.Fragment);}
}export default Boxes;【注】在react组件之间的通信是通过props属性来完成的比如父组件需要将数据传递给子组件那么组件在渲染子组件的时候直接将数据作为子组件的属性传参。 state 值传递通过 props 将 Boxes定义的属性值返回传递给 Box的
class Box extends Component {state { // props类似于state存储除key以外属于 box 的所有属性// Boxes 建立的 Box 赋值的 x 存到了 props 里// 通过 props 传递给了每个 Boxx: this.props.x,} handleClickLeft (step) { this.setState({x: this.state.x - step});}handleClickRight (step) {this.setState({x: this.state.x step});}render() { return (React.Fragmentdiv style{this.getStyles()}{this.toString()}/div button onClick{()this.handleClickLeft(10)} classNamebtn btn-primary m-2left/buttonbutton onClick{()this.handleClickRight(10)} classNamebtn btn-success m-2right/button /React.Fragment);}getStyles() {let styles {width: 50px,height: 50px,backgroundColor: pink, color: white,textAlign: center,lineHeight: 50px,borderRadius: 5px,margin: 5px,marginLeft: this.state.x,};if (this.state.x 0){styles.backgroundColor orange;}return styles;}toString(){return x: ${this.state.x}; }
}export default Box;标签传递通过 props 将Boxes 增加的Box.children子标签传递给 Box // Boxes.jsx文件render() { return (React.Fragment{this.state.boxes.map((box)(Box key {box.id} x {box.x} pBox :/p // 将 Box 的闭合标签写为双标签div{box.id}/div // 可在 Box 标签内增加其它标签属性名为 Box.children/Box // 并存储到了 props 中 ))}/React.Fragment);
}// Box.jsx 文件
render() { console.log(this.props); return (React.Fragment{this.props.children[0]} // 通过 props 所存储的 children 将增加的标签传递给Boxdiv style{this.getStyles()}{this.toString()}/div button onClick{()this.handleClickLeft(10)} classNamebtn btn-primary m-2left/buttonbutton onClick{()this.handleClickRight(10)} classNamebtn btn-success m-2right/button /React.Fragment);
}方法传递1React 子组件调用父组件的方法。
Box子组件调用Boxes父组件内的方法依旧通过props。实现在 Box 组件中触发 onClick 事件后在Boxes组件中删除key值对应的Box即在Box标签内调用Boxes标签的方法 // Boxes.jsx 文件// 1. Boxes.jsx 文件中写删除的方法handleDelete (id) {// filter: boxes列表的元素依次判断若表达式为true则留下否则删掉// 即若id不等留下来相等删除const newboxes this.state.boxes.filter((x)(x.id ! id));this.setState({boxes: newboxes})}render() { if(this.state.boxes.length 0){return div classNamealert alert-dark没有元素可以删除了!!!/div}return (// 2. 将所写删除方法定义为标签的 onDelete 属性传递给 Box会存储在 props中React.Fragment{this.state.boxes.map((box)(Box key {box.id} id{box.id} x {box.x} onDelete {this.handleDelete} pBox :/pdiv{box.id}/div /Box))}/React.Fragment);
}// Box.jsx 文件render() { return (React.Fragment{this.props.children[0]}div style{this.getStyles()}{this.toString()}/div button onClick{()this.handleClickLeft(10)} classNamebtn btn-primary m-2left/buttonbutton onClick{()this.handleClickRight(10)} classNamebtn btn-success m-2right/button// 3. Box 调用 Boxes 的删除方法 // Box 中的 Button 的 onClick 事件绑定匿名函数来调用含参的删除方法 button onClick{()this.props.onDelete(this.props.id)} classNamebtn btn-danger m-2 Delete /button/React.Fragment);
}方法传递2React 父组件调用子组件的方法。
仅能调用一个子组件方法无法调用列表子组件
// 父组件
class Boxes extends Component {// 1. Boxes 父组件中写入setChildRef (ref) {this.ChildRef ref;}// 3. Boxes 父组件中写调用 Box 子组件的方法handleReset () {this.ChildRef.handleRE()}render() { return (React.Fragment// 4. 将父组件方法绑定onClick单击事件中即可实现单击调用子组件的方法button onClick{this.handleReset} classNamebtn btn-primary Clear /button{this.state.boxes.map((box)( // 2. Boxes 父组件的 Box 子组件标签内增加 ref 属性并将 setChildRef 传递过来Box key {box.id} ref{this.setChildRef} id{box.id} x {box.x} onDelete {this.handleDelete} pBox :/pdiv{box.id}/div /Box))}/React.Fragment);}}// 子组件
class Box extends Component {state { x: this.props.x,} // 子组件中被调用的方法handleRE () {this.setState({x: 0});}render() { return (React.Fragment....../React.Fragment);}
}
5、组件使用
5.1、组件的生命周期 创建时挂载阶段
执行时机组件创建时页面加载时执行顺序constructor() - render() - componentDidMount()
constructor()组件创建的时候最先执行主要是初始化数据为事件处理程序绑定this
render()每次组件渲染触发主要是渲染UI
componentDidMOunt()组件挂载完成主要作用DOM操作发送网络请求
更新时更新阶段
执行时机1.setState() 2.组件收到props变了 3.forceUpdate()说明以上3中情况都会触发执行顺序render() - componentDidUpdate()
render():每次组件渲染触发渲染UI
componentDidUpdate()组件 状态更新完毕
预载时
执行时机组件从页面消失 5.2、动态更新initialValue的值
[antd: Form.Item] defaultValue will not work on controlled Field. You should use initialValues o 原因antd禁止在form.item下的组件使用默认属性解决办法删除defaultValue,在中使用initialValue{{ parentId: parentId }}代替如果要动态更新 parentId的值又会导致下面的问题
React does not recognize the initialValue prop on a DOM element. **原因**不能通过这种方法更新parentId的值想要更新props中的值要通过form.setFieldsValue({ parentId: parentId })进行更改
你不能用控件的 value 或 defaultValue 等属性来设置表单域的值默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新你需要用 setFieldsValue 来更新。
由上可知表单中不能设置默认值要想设置默认值必须通过form中的initial Values进行设置但是其又不能动态更新想要达到动态更新的效果必须使用form中的setFieldsValue进行更新需要检测parentId的变化从而对parentId进行修改固需要在useEffect中使用setFieldsValue
如果需要在父组件中得到子组件的form表单中的值可以通过函数传参的方式将子组件的form对象传递给父组件这样父组件得到子组件的form对象就可以通过getFieldValue得到表单的值了。 const [form] Form.useForm()//将子组件的form传递给父组件使得父组件可以取到子组件form中的categorieName的值props.setForm(form)// 动态更新parentId的值useEffect(() {form.setFieldsValue({ parentId: parentId })}, [parentId])import React, { Fragment, useEffect } from react
import { Form, Input, Select } from antd
import { useForm } from antd/lib/form/Form;const { Option } Select;export default function AddForm(props) {const { categorys, parentId } propsconst [form] Form.useForm()console.log(parentId)// 动态更新parentId的值useEffect(() {form.setFieldsValue({ parentId: parentId })}, [parentId])return (Fragment{/* initialValues不能被动态更新需要使用form.setFieldsValues进行动态更新将其放在useEffect中 */}Form form{form}span所属分类/spanForm.ItemnameparentIdrules{[{required: true,message: Please select category!,},]}{/* 表单中不能使用默认属性defaultValue在form中使用initialValues{{}}代替 */}Select Option value0一级分类/Option{categorys.map(c Option key{c._id} value{c._id}{c.name}/Option)}/Select/Form.Itemspan分类名称/spanForm.ItemnamecategoryNamerules{[{required: true,message: Please input your categoryName!}]}Input placeholder添加分类 //Form.Item/Form/Fragment )
}
// 告警标签
// 动态更新initialValue值
changeMissLevel () {const{form} this.props;form.setFieldsValue({missLevel:222});
}render(){Form.Item{getFieldDecorator(missLevel,{initialValue:this.state.missLevel})(SelectonChange{this.changeMissLevel}Option value 1a/OptionOption value 2b/Option/Select)}/
}
5.3、遍历对象与数组
遍历对象与数组
// 遍历对象
const object {a:1,b:2};
for(let key in object){console.log(key);console.log(object[key]);
}// 遍历数组
const array [1,2,3];
const array1 [{a:1},{b:2}];for(let key in array){console.log(array[key]);
}
for(let key in array1){console.log(array[key].a);console.log(array[key].b);
}对象动态值获取或作为键
// 动态值作为键
const obj {a:1,b:2};
let ccc c;
obj[ccc] 3;
// 对象赋值
obj.d 4;
// 对象获取值
let ddd obj.d;// 对象动态值获取
const data {a:1,b:2};
let aaa a;
data[aaa]
对象与字符串的转换
// 对象转字符串
const obj {a:1}
JSON.String(obj );
// 字符串转对象
String a ;
JSON.parse(a);// join与split
const aa [1,2];
const bb 1,2;
bb aa.join(,);
aa bb.split(,);
非空判断
// 判断是否不为空
ifNotNull (value:any) {if( value ! undefined value ! null value ! null value ! NULL value ! [] value ! value ! {} value ! [] ){return true; } else {return false;}
}// 判断是否为空
ifNotNull (value:any) {if( value undefined ||value null ||value null ||value NULL ||value [] ||value ||value {} ||value [] ||){return true; } else {return false;}
}