当前位置: 首页 > news >正文

网站建设具体建设流程广东省门户网站建设的现状

网站建设具体建设流程,广东省门户网站建设的现状,珠海建设工程交易中心网站,徐州建站软件文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSX#x1f349;JSX简介与使用#x1f349;JSX语法规则 1.4模块与组件#x1f349;模块#x1f349;组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件#x1f349;函数式组件#x1f349… 文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSXJSX简介与使用JSX语法规则 1.4模块与组件模块组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件函数式组件类式组件 2.2组件实例的三大属性state属性props属性refs属性1.字符形式的ref2.回调函数形式的ref3.使用createRefreact最推荐的形式 2.3事件处理2.4 受控组件和非受控组件非受控组件受控组件 2.5高阶函数与函数柯里化2.6生命周期引入react生命周期旧react生命周期新 2.7虚拟DOM与DOM Diffing算法 3.react脚手架3.1创建与启动3.2react脚手架项目结构默认文件编码流程 3.3TodoList案例todoList案例提要 4.React ajax4.1简介4.2实现4.3配置代理4.4github搜索案例axios版本提要pubsub版本提要Fetch版本提要了解 5.React路由5.1相关理解对SPA应用的理解路由的理解react-router的理解 5.2路由的基本使用5.3路由组件与一般组件5.4NavLink与封装NavLink5.5Switch的使用5.6解决样式丢失问题5.7路由的模糊匹配与严格匹配5.8Redirect的使用5.9嵌套路由5.10向路由组件传递参数向路由组件传递params参数向路由组件传递search参数向路由组件传递state参数 5.11push与repalce5.12编程式路由导航5.13withRouter的使用5.14BrowserRouter与HashRouter 6.React UI组件库6.1流行的开源React UI组件库material-ui(国外)ant-design(国内蚂蚁金服) 7.Redux7.1Redux简介7.2Redux的工作流程redux原理图redux的三个核心概念 7.3求和案例纯react版redux精简版redux完整版异步action版 7.4初识react-redux对react-redux的理解连接容器组件与UI组件react-redux基本使用 7.5react-redux的优化7.6数据共享7.7纯函数7.8redux开发者工具7.9最终版7.10项目打包 前端学习–React部分 前言 在学习React之前需要掌握的JavaScript基础知识有class类、ES6语法规范、npm包管理器、原型、原型链、数组的常用方法、模块化。如果上述知识点你有些淡忘请前往我的博客主页进行查看。 在讲解过程中老师会复习旧的知识点请前往我的gitee链接中进行查看 https://gitee.com/marygood/tkreactstudy 下载文件去这里https://www.bootcdn.cn/下载的时候看好文件名 1.React简介 官网给出的定义用于构建用户界面的JavaScript库只关注页面。 通俗定义将数据渲染为HTML视图的开源JavaScript库。 学习React的原因 原生JS操作DOM繁琐且效率低因为用DOM-API操作UI JS直接操作DOM会使浏览器进行大量的重绘重排 原生JS没有组件化编码方案代码复用率低 1.1React的特点 采用组件化模式声明式编码提高开发效率及组件复用率 在React Native中可以使用React语法进行移动端开发 使用虚拟DOM优秀的Diffing算法尽量减少与真实DOM的交互 注最后一点很重要它是React高效的原因。 问为什么使用虚拟DOM因为操作页面的代价比操作js大得多。 实现流程把数据交给React它便会拿着这些数据生成虚拟DOM之后将虚拟DOM转换为真实DOM最后将这些呈现在页面上。 补充数据放在状态state中不是随便放置的。 1.2引入文件 1.react.js 核心库核心库要在react-dom之前引入 2.react-dom.js 提供操作DOM的react扩展库 3.babel.min.js解析JSX语法代码转为JS代码的库即ES6ES5;JSXJS 需要注意的是引入文件一定要按照这个顺序。 1.3JSX JSX简介与使用 全称 JavaScript XML 是react定义的一种类似于XML的JS扩展语法本质是React.createElement(component, props, ...children)方法的语法糖。JXS最终产生的虚拟DOM就是一个JS对象。 详细代码请前往码云链接。 JSX语法规则 1.定义虚拟DOM时不要写引号 2.标签中混入js表达式时用{} 3.样式的类名指定不要用class要用className 4.内联样式要用style{{key:value}}的形式去写 5.只有一个根标签 6.标签必须闭合 7.标签首字母 ​ 1小写默认为html标签good/good //不是html标签–报错 ​ 2大写默认为组件Good/Good //未定义组件–报错 1.4模块与组件 模块 向外界提供特定功能的js程序。随着业务逻辑增加代码越来越多且复杂此时js一般会拆成多个js文件来编写一般一个js文件就是一个模块作用复用js简化js的编写提高js的运行效率模块化当应用的js都以模块来编写的, 这个应用就是一个模块化的应用 组件 用来实现局部功能效果的代码和资源的集合(html/css/js/image等等)。比如一个功能齐全的Header栏就是一个组件。复用编码, 简化项目编码, 提高运行效率组件化当应用是以多组件的方式实现, 这个应用就是一个组件化的应用 1.5安装开发者工具 我自己直接在谷歌应用商店下载的现在的发布者已经变为Meta。 打开扩展程序找到安装好的React Developer Tool点击详情并勾选上以下内容。 2.React面向组件编程 2.1创建组件 函数式组件 简单组件没有state本身没有三大属性不过通过hooks也有了三大属性。 类式组件 复杂组件有state有三大属性。 2.2组件实例的三大属性 state属性 state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)组件被称为状态机, 通过更新组件的state来更新对应的页面显示(重新渲染组件) 代码实例切换天气状态简写版 script typetext/babel// 实际开发中一定是写精简版本的// 1.创建组件class Weather extends React.Component{// 初始化状态state{isHot:false,wind:微风}render() {// 读取状态(解构赋值)const {isHot,wind} this.state// 注意此处React事件绑定的写法return h1 onClick{this.changeWeather}今天天气{isHot ? 热:凉}{wind}/h1}// 和完整写法比这里用了箭头函数就不再使用构造器changeWeather() {// 获取原来的isHot值const isHotthis.state.isHot// 注意状态不可以直接更改必须通过setState进行更新且更新是一种合并不是替换。// this.state.isHot!isHot //错误写法this.setState({isHot:!isHot})}}// 2.渲染组件到页面ReactDOM.render(Weather/,document.getElementById(test))/script这里需要注意的是在render函数中创建虚拟DOM时直接在标签中绑定事件且事件写法不同于原生JS如原生JS中的onclick事件在react中要写成onClick其他同理。其次需要注意的是状态数据不能直接修改或更新要使用setState。 props属性 通过标签属性创建虚拟DOM时直接添加的数据从组件外向组件内传递变化的数据 传递props即传递标签属性 – props批量传递标签属性 组件标签的所有属性都保存在props中 props是只读的,不要在组件内部修改props 如果想对标签属性进行类型、必要性限制需要引入prop-types库不是必须的看情况 代码实例 自定义用来显示人员信息 标准形式 – 写在外部 !DOCTYPE html html langen headmeta charsetUTF-8titlehello_react/title /head body!-- 准备好一个容器 --div idtest/divdiv idtest1/divdiv idtest2/div!-- 引入依赖 ,引入的时候必须就按照这个步骤--!-- 引入react核心库 --script src../js/react.development.js typetext/javascript/script!-- 引入react-dom用于支持react操作DOM --script src../js/react-dom.development.js typetext/javascript/script!-- 引入babel用于将jsx转为js --script src../js/babel.min.js typetext/javascript/script!--引入对于组件标签的限制--script src../js/prop-types.js/script!-- 此处一定要写babel不写会默认为js将报错 --script typetext/babel// 1.创建组件class Person extends React.Component{render() {console.log(this)const {name,age,sex} this.propsreturn(ulli姓名{name}/lili性别{sex}/lili年龄{age1}/li/ul)}}// 对标签属性进行类型、必要性限制Person.propTypes{name:PropTypes.string.isRequired, //限制name必传且为字符串sex:PropTypes.string,//限制sex为字符串age:PropTypes.number,//限制age为数值speak:PropTypes.func,//现在speak为函数}// 指定默认标签属性值Person.defaultProps{sex:男,age:18}// 2.渲染组件到页面ReactDOM.render(Person nameBob age{19} speak{speak}/,document.getElementById(test))ReactDOM.render(Person nameTom sex男/,document.getElementById(test1))// 另一种 写法const p{name:Lily,age:30,sex:女}ReactDOM.render(Person {...p}/,document.getElementById(test2))function speak() {console.log(我说话了)}/script /body /html 简写形式 – 写在内部 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babel// 1.创建组件class Person extends React.Component{// 对标签属性进行类型、必要性限制static propTypes{name:PropTypes.string.isRequired, //限制name必传且为字符串sex:PropTypes.string,//限制sex为字符串age:PropTypes.number,//限制age为数值}// 指定默认标签属性值static defaultProps{sex:男,age:18}render() {console.log(this)const {name,age,sex} this.propsreturn(ulli姓名{name}/lili性别{sex}/lili年龄{age1}/li/ul)}}// 2.渲染组件到页面ReactDOM.render(Person nameBob/,document.getElementById(test))/script注意 首字母小写的propTypes是类里的属性规则首字母大写的PropTypes是prop-types库里的内置对象 函数组件使用props !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babel// 注意到目前学习阶段函数组件只能使用三大属性中propsfunction Person(props){const {name,age,sex} propsreturn(ulli姓名{name}/lili性别{sex}/lili年龄{age}/li/ul)}// 渲染组件到页面ReactDOM.render(Person nameBob sexmale age12/,document.getElementById(test))/scriptrefs属性 组件内的标签可以定义ref属性来标识自己。this.refs可以拿到真实DOM。 1.字符形式的ref !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{// 展示左侧输入框数据showData () {const {input1}this.refsalert(input1.value)// console.log(this)}// 展示右侧输入框的数据showDataRight(){const {input2}this.refsalert(input2.value)}render(){return (divinput refinput1 typetext placeholder点击弹出提示数据 /nbsp;button onClick {this.showData}点击/buttonnbsp;input refinput2 onBlur{this.showDataRight} typetext placeholder失去焦点弹出提示数据 //div)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/* ref与refs介绍1.只要有ref标识就会有refs属性有ref就不用id了功能类似2.这节使用的字符串形式的ref比较老旧不推荐使用,因为效率低*//script2.回调函数形式的ref 回调函数一种特殊的函数。它会作为参数传递给另一个函数并在该函数被调用执行完毕后执行。 script typetext/babelclass Demo extends React.Component{// 展示左侧输入框数据showData () {const {input1}thisalert(input1.value)}// 展示右侧输入框的数据showDataRight(){const {input2}thisalert(input2.value)} // currentNode当前节点两种写法一种是完整版一种是精简版render(){return (divinput ref{(currentNode){this.input1currentNode}} typetext placeholder点击弹出提示数据 /nbsp;button onClick {this.showData}点击/buttonnbsp;input ref{ c this.input2c } onBlur{this.showDataRight} typetext placeholder失去焦点弹出提示数据 //div)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/script3.使用createRefreact最推荐的形式 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{// React.createRef调用后可以返回一个容器该容器可以存储被ref所标识的节点该容器的使用是需要一一对应的myRefReact.createRef()// myRefRightReact.createRef()// 展示左侧输入框数据showData () {alert(this.myRef.current.value)}// 展示右侧输入框的数据showDataRight(){alert(this.myRefRight.current.value)} // currentNode当前节点两种写法一种是完整版一种是精简版render(){return (divinput ref{this.myRef} typetext placeholder点击弹出提示数据 /nbsp;button onClick {this.showData}点击/buttonnbsp;input ref{this.myRefRightReact.createRef()} onBlur{this.showDataRight} typetext placeholder失去焦点弹出提示数据 //div)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/* createRef(API)这种方式是目前react最推荐的。 */2.3事件处理 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{/* 1.通过onXxx属性指定事件处理函数注意大小写a.React使用的是自定义合成事件而不是使用原生DOM事件 -- 为更好的兼容性b.React中的事件是通过事件委托方式处理的委托给组件最外层的元素-- 为高效2.通过event.target得到发生事件的DOM元素对象 -- 不要过度使用ref有事件就不用ref*/// 创建ref容器myRefReact.createRef()// 展示左侧输入框数据showData () {alert(this.myRef.current.value)}// 展示右侧输入框的数据showDataRight(event){alert(event.target.value)} // currentNode当前节点两种写法一种是完整版一种是精简版render(){return (divinput ref{this.myRef} typetext placeholder点击弹出提示数据 /nbsp;button onClick {this.showData}点击/buttonnbsp;input onBlur{this.showDataRight} typetext placeholder失去焦点弹出提示数据 //div)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/script2.4 受控组件和非受控组件 非受控组件 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{login (event) {event.preventDefault() //阻止表单提交const {saveName,savePwd}thisalert(姓名${saveName.current.value}密码${savePwd.current.value})}render(){return (form actionhttp://www.baidu.com onSubmit{this.login}用户名input ref{this.saveNameReact.createRef()} type text name username/密码input ref{this.savePwdReact.createRef()} type password name password/button登录/button/form)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/* 现用现取就属于非受控组件 *//script受控组件 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{saveName (event) {this.setState({username:event.target.value})} savePwd(event){this.setState({password:event.target.value})}login (event) {event.preventDefault() //阻止表单提交const {username,password} this.state //注意username和password是值alert(姓名${username},密码${password})}render(){return (form actionhttp://www.baidu.com onSubmit{this.login}用户名input onChange{this.saveName} type text name username/密码input onChange{this.savePwd} type password name password/button登录/button/form)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/* 随着输入维护状态就属于受控组件。类似vue中的双向数据绑定通俗理解通过ref就是非受控通过change就是受控。建议写受控组件*//script2.5高阶函数与函数柯里化 !DOCTYPE html html langen headmeta charsetUTF-8titlehello_react/title /head body!-- 准备好一个容器 --div idtest/div!-- 引入依赖 ,引入的时候必须就按照这个步骤--!-- 引入react核心库 --script src../js/react.development.js typetext/javascript/script!-- 引入react-dom用于支持react操作DOM --script src../js/react-dom.development.js typetext/javascript/script!-- 引入babel用于将jsx转为js --script src../js/babel.min.js typetext/javascript/script!--引入对于组件标签的限制--script src../js/prop-types.js/script!-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{// saveFormData就是高阶函数saveFormData (dataType) {return(event){// 调用变量形式的对象属性名// 可以理解为加上中括号的dataType就成为了一个属性this.setState({[dataType]:event.target.value})}} login (event) {event.preventDefault() //阻止表单提交const {username,password} this.state //注意username和password是值alert(姓名${username},密码${password})}// 能保证onChange等于的是一个函数即可无需过度在意加不加括号render(){return (form actionhttp://www.baidu.com onSubmit{this.login}用户名input onChange{this.saveFormData(username)} type text name username/密码input onChange{this.saveFormData(password)} type password name password/button登录/button/form)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/* 高阶函数如果一个函数符合下面2个规范中的任何一个那么该函数就是高阶函数。1.若A函数接收的参数是一个函数那么A就可以称之为高阶函数2.若A函数调用的返回值依然是一个函数那么A就可以称之为高阶函数常见的高阶函数有Promise、setTimeout、arr.map()等等函数的柯里化通过函数调用继续返回函数的方式实现多次接收参数最后统一处理的函数编码形式。*//script /body /html不过也不是一定要用函数的柯里化实现下面介绍不用函数柯里化实现的方法 !-- 此处一定要写babel不写会默认为js将报错 --script typetext/babelclass Demo extends React.Component{// saveFormData就是高阶函数saveFormData (dataType,event) {this.setState({[dataType]:event.target.value})} login (event) {event.preventDefault() //阻止表单提交const {username,password} this.state //注意username和password是值alert(姓名${username},密码${password})}// 能保证onChange等于的是一个函数即可无需过度在意加不加括号render(){return (form actionhttp://www.baidu.com onSubmit{this.login}用户名input onChange{event this.saveFormData(username,event)} type text name username/密码input onChange{event this.saveFormData(password,event)} type password name password/button登录/button/form)}}// 渲染组件到页面ReactDOM.render(Demo/,document.getElementById(test))/script2.6生命周期 引入 React组件中包含一系列生命周期回调函数。我们在定义组件时会在特定的生命周期回调函数中做特定的工作。生命周期回调函数也可以称为生命周期钩子函数 生命周期函数 生命周期钩子。 补充react写法 行内样式写法style{{opacity:opacity}}。对象中属性名和属性值相同时触发简写{opacityopacity}简写为{opacity}。 react生命周期旧 1.初始化阶段: 由ReactDOM.render()触发—初次渲染1constructor()2componentWillMount()3render() 常用初始化或者更新渲染4componentDidMount() 常用一般在这个钩子中做一些初始化的事如开启定时器、发送网络请求、订阅消息 2.更新阶段: 由组件内部this.setSate()或父组件重新render触发1shouldComponentUpdate() -- 闸门返回值是布尔值为true时执行后续代码2componentWillUpdate()3render()4componentDidUpdate() 3.卸载组件: 由ReactDOM.unmountComponentAtNode()触发1componentWillUnmount() 常用一般在这个钩子中做一些收尾的事如关闭定时器、取消订阅消息react生命周期新 1.初始化阶段: 由ReactDOM.render()触发—初次渲染1constructor()2getDerivedStateFromProps3render() 常用初始化或者更新渲染4componentDidMount() 常用一般在这个钩子中做一些初始化的事如开启定时器、发送网络请求、订阅消息 2.更新阶段: 由组件内部this.setSate()或父组件重新render触发1getDerivedStateFromProps2shouldComponentUpdate()3render()4getSnapshotBeforeUpdate --5componentDidUpdate() 3.卸载组件: 由ReactDOM.unmountComponentAtNode()触发1componentWillUnmount() 常用一般在这个钩子中做一些收尾的事如关闭定时器、取消订阅消息 注新出的也不常用 2.7虚拟DOM与DOM Diffing算法 经典面试题 1react/vue中的key有什么作用key的内部原理是什么 2为什么遍历列表时key最好不要用index?1.虚拟DOM中key的作用1简单的说key是虚拟DOM对象的标识在更新显示时key起着极其重要的作用。2详细的说当状态中的数据发生变化时react会根据【新数据】生成【新的虚拟DOM】随后react进行【新虚拟DOM】与【旧虚拟DOM】的diff比较比较规则如下a.旧虚拟DOM中找到了与新虚拟DOM相同的key(1) 若虚拟DOM中内容没变, 直接使用之前的真实DOM(2) 若虚拟DOM中内容变了, 则生成新的真实DOM随后替换掉页面中之前的真实DOMb.旧虚拟DOM中未找到与新虚拟DOM相同的key根据数据创建新的真实DOM随后渲染到到页面 2.用index作为key可能会引发的问题1若对数据进行逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 界面效果没问题, 但效率低。2如果结构中还包含输入类的DOM如input虚拟DOM中标签属性少input没有value属性会产生错误DOM更新 界面有问题。3注意 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作仅用于渲染列表用于展示使用index作为key是没有问题的。 3.开发中如何选择key?1最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。2如果确定只是简单的展示数据用index也是可以的。3.react脚手架 3.1创建与启动 全局安装npm i -g create-react-app切换到想要创建项目的目录使用命令create-react-app hello-react。hello-react是文件名用VSCode打开文件并在终端软件内启动项目npm start 3.2react脚手架项目结构 默认文件 public -- 静态资源文件夹 favicon.icon -- 网站页签图标 index.html -- 主页面 logo192.png -- logo图 logo512.png -- logo图 manifest.json -- 应用加壳的配置文件 robots.txt -- 爬虫协议文件src -- 源码文件夹 App.css -- App组件的样式App.js里引用 App.js -- App组件子组件可以都写在components文件夹里子组件文件夹首字母大写。路由组件写在pages文件夹 App.test.js -- 用于给App做测试 index.css -- 样式通用样式入口文件里引用 index.js -- 入口文件 logo.svg -- logo图 reportWebVitals.js -- 页面性能分析文件(需要web-vitals库的支持) setupTests.js -- 组件单元测试的文件(需要jest-dom库的支持)编码流程 拆分组件: 拆分界面,抽取组件 实现静态组件: 使用组件实现静态页面效果 实现动态组件:3.1 动态显示初始化数据3.1.1 数据类型3.1.2 数据名称3.1.3 保存在哪个组件?3.2 交互(从绑定事件监听开始)3.3TodoList案例 详细代码见前言中的gitee链接。 todoList案例提要 写法的注意class -- className、style -- style{{}}动态初始化列表如何确定将数据放在哪个组件的state中 1某个组件使用放在其自身的state中 2某些组件使用放在他们共同的父组件state中官方称此操作为状态提升关于父子之间通信 1【父组件】给【子组件】传递数据通过props传递 2【子组件】给【父组件】传递数据通过props传递要求父提前给子传递一个函数注意defaultChecked 和 checked的区别类似的还有defaultValue 和 value状态在哪里操作状态的方法就在哪里 4.React ajax 4.1简介 React本身只关注于界面, 并不包含发送ajax请求的代码前端应用需要通过ajax请求与后台进行交互(json数据)react应用中需要集成第三方ajax库(或自己封装但是基本不会自己封装) 4.2实现 jQuery: 要操作DOM并且比较重, 如果需要另外引入不建议使用axios: 轻量级, 建议使用 1封装XmlHttpRequest对象的ajax 2promise风格 3可以用在浏览器端和node服务器端 4.3配置代理 方法一 在package.json中追加配置proxy:http://localhost:5000 优点配置简单前端请求资源时可以不加任何前缀。缺点不能配置多个代理。工作方式上述方式配置代理当请求了3000不存在的资源时那么该请求会转发给5000 优先匹配前端资源 方法二 创建代理配置文件在src文件夹下创建setupProxy.js文件。 编写setupProxy.js配置具体代理规则 //这个文件名是固定的不可改 const proxy require(http-proxy-middleware)module.exports function(app) {app.use(proxy(/api1, { //api1是需要转发的请求(所有带有/api1前缀的请求都会转发给5000)target: http://localhost:5000, //配置转发目标地址(能返回数据的服务器地址)changeOrigin: true, //控制服务器接收到的请求头中host字段的值(可以欺骗一下浏览器)/*changeOrigin设置为true时服务器收到的请求头中的host为localhost:5000changeOrigin设置为false时服务器收到的请求头中的host为localhost:3000changeOrigin默认值为false但我们一般将changeOrigin值设为true*/pathRewrite: {^/api1: } //去除请求前缀/api1保证交给后台服务器的是正常请求地址(必须配置)}),proxy(/api2, { target: http://localhost:5001,changeOrigin: true,pathRewrite: {^/api2: }})) }说明 优点可以配置多个代理可以灵活的控制请求是否走代理。 缺点配置繁琐前端请求资源时必须加前缀。 react 18版本写法在后续的github案例中我自己用的这个。 //react 18版本写法 const {createProxyMiddleware} require(http-proxy-middleware)module.exports function (app) {app.use(createProxyMiddleware(/api1, {target: http://localhost:5000,changeOrigin: true,pathRewrite: {^/api1: }})) }4.4github搜索案例 详细代码在前言的gitee链接中。 axios版本提要 连续解构赋值重命名 const {keyWordElement:{value:keyWord}} this三元表达式 isFirst ? h2欢迎使用输入关键字随后点击搜索/h2 : isLoading ? h2Loading....../h2 : err ? h2 style{{color:red}}{err}/h2 如果你说什么都展现不出效果 //App.jsx文件 export default class App extends Component{...updateAppState (stateObj) {this.setState({...stateObj})}... }pubsub版本提要 工具库: PubSubJS 下载: npm install pubsub-js --save 使用: 1) import PubSub from ‘pubsub-js’ //引入 2) PubSub.subscribe(‘delete’, function(data){ }); //订阅 3) PubSub.publish(‘delete’, data) //发布 4) 要在组件的componentWilUnmount中取消订阅 注谁用谁订阅谁有订阅者所需的数据谁就发布。Fetch版本提要了解 发送ajax请求的方法原生AJAXxhrjQuery对xhr的封装axios对xhr的封装fetch不是库是windows内置且是Promise风格。 注有些文章拉踩不过还是要以主流为主。 fetch的特点关注分离兼容性不高老版本浏览器不支持。5.React路由 5.1相关理解 对SPA应用的理解 单页Web应用single page web applicationSPA。整个应用只有一个完整的页面。点击页面中的链接不会刷新页面只会做页面的局部更新。数据都需要通过ajax请求获取, 并在前端异步展现。 路由的理解 什么是路由 一个路由就是一个映射关系(key:value)key为路径, value可能是function或component 路由的分类 1.后端路由 理解value是function, 用来处理客户端提交的请求。注册路由 router.get(path, function(req, res))工作过程当node接受到一个请求时根据请求路径找到匹配的路由调用路由中的函数来处理请求返回响应数据。 2.前端路由 浏览器端路由value是component用于展示页面内容。注册路由: Route path/test component{Test}工作过程当浏览器的path变为/test时, 当前路由组件就会变为Test组件。 react-router的理解 react的一个插件库。 安装npm i react-router-dom5。注意是5版本 专门用来实现一个SPA应用。 基于react的项目基本都会用到此库。 5.2路由的基本使用 明确好界面中的导航区、展示区导航区的a标签改为Link标签 Link to/xxxxx Demo/Link展示区写Route标签进行路径的匹配Route path/xxxx component{Demo}/App的最外侧包裹了一个BrowserRouter或HashRouter注意详细代码见gitee。 5.3路由组件与一般组件 写法不同 一般组件Demo/ 路由组件: Route path/demo component{Demo}/ 存放文件位置不同 一般组件在components文件中路由组件在pages文件中 接收到的props不同 一般组件写组件标签时传递了什么就能收到什么 路由组件接收到三个固定的属性 history go: f go(n) goBack: f goBack() goForward: f goForward() push: f push(path,state) replace: f replace(path, state)location pathname: /about search: state: undefinedmatch params: {} path: /about url: /about5.4NavLink与封装NavLink NavLink可以实现路由链接的高亮通过activeClassName指定样式名标签体内容是一个特殊的标签属性通过this.props.children可以获取标签体内容注意详细代码见gitee。 5.5Switch的使用 通常情况下path和component是一一对应的关系。Switch可以提高路由匹配效率(单一匹配)。详细代码见gitee。 5.6解决样式丢失问题 public/index.html 中引入样式时不写./写/常用) link relstylesheet hrefcss/bootstrap.csspublic/index.html 中引入样式时不写﹒/写%PUBLIC_URL%常用) link relstylesheet href%PUBLIC_URL%/css/bootstrap.css使用HashRouter (不常用) import React from react; import ReactDOM from react-dom/client; import App from ./App; import {BrowserRouter, HashRouter} from react-router-dom;const root ReactDOM.createRoot(document.getElementById(root)); root.render(HashRouterApp//HashRouter );5.7路由的模糊匹配与严格匹配 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】且顺序要一致)开启严格匹配Route exact{true} path/about component{About}/严格匹配不要随便开启需要再开有些时候开启会导致无法继续匹配二级路由 5.8Redirect的使用 一般写在所有路由注册的最下方当所有路由都无法匹配时跳转到Redirect指定的路由。 具体编码: SwitchRoute path/about component{About}/Route path/home component{Home}/Redirect to/about/ /Switch5.9嵌套路由 注册子路由时要写上父路由的path值路由的匹配是按照注册路由的顺序进行的注意详细代码见gitee 5.10向路由组件传递参数 向路由组件传递params参数 路由链接(携带参数)Link to/demo/test/tom/18}详情/Link 注册路由(声明接收)Route path/demo/test/:name/:age component{Test}/ 接收参数const {id,title} this.props.match.params 向路由组件传递search参数 路由链接(携带参数)Link to /demo/test?nametomage18}详情/Link 注册路由(无需声明正常注册即可)Route path/demo/test component{Test}/ 接收参数const isearch} this.props.location 备注获取到的search是urlencoded编码字符串需要借助querystring解析 向路由组件传递state参数 路由链接(携带参数) Link to{{path: /demo/test,state:{name : tom ,age:18]}}详情/Link注册路由(无需声明正常注册即可):Route path/demo/test component{Test}/接收参数this.props.location.state 备注刷新也可以保留住参数 5.11push与repalce push:留下记录repalce:不留记录注意详细代码见gitee 5.12编程式路由导航 借助this.prosp.history对象上的API对操作路由跳转、前进、后退 this.prosp.history.push() this.prosp.history.replace() this.prosp.history.goBack() this.prosp.history.goForward() this.prosp.history.go()注意详细代码见gitee 5.13withRouter的使用 withRouter可以加工一般组件让一般组件具备路由组件所特有的APIwithRouter的返回值是一个新组件 import React, {Component} from react; import {withRouter} from react-router-dom;class Header extends Component {back () {this.props.history.goBack()}forward () {this.props.history.goForward()}go () {this.props.history.go(2)}render() {// console.log(Header组件收到的props是, this.props)return (divdiv classNamepage-headerh2React Router Demo/h2button onClick{this.back}回退/buttonbutton onClick{this.forward}前进/buttonbutton onClick{this.go}go/button/div/div);} }export default withRouter(Header);5.14BrowserRouter与HashRouter 底层原理不一样: (1) BrowserRouter使用的是H5的history API不兼容IE9及以下版本。 (2) HashRouter使用的是URL的哈希值path表现形式不一样 (1) BrowserRouter的路径中没有#,例如localhost:3000/demo/test (2) HashRouter的路径包含#,例如 localhost:3000/#/demo/test刷新后对路由state参数的影响 (1) BrowserRouter没有任何影响因为state保存在history对象中。 (2) HashRouter刷新后会导致路由state参数的丢失。备注: HashRouter可以用于解决一些路径错误相关的问题。总的来讲BrowserRouter常用。 6.React UI组件库 6.1流行的开源React UI组件库 material-ui(国外) 官网 http://www.material-ui.com/#/ Githubhttps://github.com/callemall/material-ui ant-design(国内蚂蚁金服) 官网: https://ant.design/index-cn Github: https://github.com/ant-design/ant-design/ 7.Redux 7.1Redux简介 什么是Redux redux是一个专门用于做状态管理的JS库(不是react插件库)。它可以用在react, angular, vue等项目中, 但基本与react配合使用。作用: 集中式管理react应用中多个组件共享的状态。 什么情况下需要使用redux? 某个组件的状态需要让其他组件可以随时拿到共享。一个组件需要改变另一个组件的状态通信。总体原则能不用就不用, 如果不用比较吃力才考虑使用。 7.2Redux的工作流程 redux原理图 redux的三个核心概念 action 动作的对象包含2个属性 type标识属性, 值为字符串, 唯一, 必要属性data数据属性, 值类型任意, 可选属性 例子{ type: ADD_STUDENT,data:{name: tom,age:18} } reducer 用于初始化状态、加工状态。加工时根据旧的state和action 产生新的state的纯函数。 store 将state、action、reducer联系在一起的对象如何得到此对象? import {createStore} from ‘redux’import reducer from ‘./reducers’const store createStore(reducer) 此对象的功能? getState(): 得到statedispatch(action): 分发action, 触发reducer调用, 产生新的statesubscribe(listener): 注册监听, 当产生了新的state时, 自动调用 7.3求和案例 纯react版 详细代码见gitee。 redux精简版 store.js: 引入redux中的createStore函数创建一个storecreatestore调用时要传入一个为其服务的reducer记得暴露store对象 count_reducer.js: reducer的本质是一个函数接收: preState,action返回加工后的状态reducer有两个作用:初始化状态加工状态reducer被第一次调用时是store自动触发的传递的preState是undefined 在index.js中检测store中状态的改变一旦发生改变重新渲染App/备注: redux只负责管理状态至于状态的改变驱动着页面的展示要靠我们自己写。注意详细代码见gitee redux完整版 新增文件: count_action.js 专门用于创建action对象constant.js放置容易写错的type值 注意详细代码见gitee 异步action版 明确:延迟的动作不想交给组件自身想交给action 何时需要异步action:想要对状态进行操作但是具体的数据靠异步任务返回。 具体编码: yarn add redux-thunk并配置在store中创建action的函数不再返回一般对象而是一个函数该函数中写异步任务。异步任务有结果后分发一个同步的action去真正操作数据。 备注异步action不是必须要写的完全可以自己等待异步任务的结果了再去分发同步action 注意详细代码见gitee 7.4初识react-redux 对react-redux的理解 连接容器组件与UI组件react-redux基本使用 明确两个概念: UI组件:不能使用任何redux的api只负责页面的呈现、交互等。容器组件:负责和redux通信将结果交给UT组件。 如何创建一个容器组件-----靠react-redux 的connect函数 connect(mapStateToProps,mapDispatchToProps)(UI组件)mapstateToProps:映射状态返回值是一个对象mapDispatchToProps:映射操作状态的方法返回值是一个对象 备注1容器组件中的store是靠props传进去的而不是在容器组件中直接引入 备注2mapDispatchToProps也可以是一个对象 注意详细代码见gitee 7.5react-redux的优化 简写mapDispatch Provider组件的使用 整合UI组件与容器组件 容器组件和UI组件组合成一个文件 无需自己给容器组件传递store给App/包裹一个Provider store{store}即可。 使用了react-redux后也不用再自己检测redux中状态的改变了容器组件可以自动完成这个工作。 mapDispatchToProps也可以简单的写成一个对象 一个组件要和redux“打交道”要经过哪几步? 定义好UI组件—不暴露 引入connect生成一个容器组件并暴露写法如下: connect( state ({key:value}) {key : xxxxxAction} )(UI组件)在UI组件中通过this.props.xxxxxxx读取和操作状态 注意详细代码见gitee 7.6数据共享 定义一个Pserson组件和Count组件通过redux共享数据 为Person组件编写: reducer、action配置constant常量。 重点: Person的reducer和Count的Reducer要使用combineReducers进行合并合并后的总状态是一个对象 交给store的是总reducer最后注意在组件中取出状态的时候记得“取到位”。 注意详细代码见gitee 7.7纯函数 一类特别的函数:只要是同样的输入(实参)必定得到同样的输出(返回)必须遵守以下一些约束 不得改写参数数据不会产生任何副作用例如网络请求输入和输出设备不能调用Date.now)或者Math.random()等不纯的方法 redux的reducer函数必须是一个纯函数 7.8redux开发者工具 首先在Google浏览器中下载扩展程序Redux DevTools 安装终端输入npm i redux-devtools-extension store中进行配置 import {composewithDevTools} from redux-devtools-extension const store createStore(allReducer,composelithDevTools(applyMiddleware(thunk)))7.9最终版 所有变量名字要规范尽量触发对象的简写形式。reducers文件夹中编写index.js专门用于汇总并暴露所有的reducer注意详细代码见gitee 7.10项目打包 打包npm run build下载插件npm i serve -g启动serve build注意在实际开发中需要把build交给后端人员再由后端人员配置到服务器中。
http://www.zqtcl.cn/news/151410/

相关文章:

  • 专业网站优化推广网站核查怎么抽查
  • 牡丹江站salong wordpress
  • 网站建设公司做网站要多少费用有哪些外国网站国内可以登录的
  • 天津建站平台网页制作免费的素材网站
  • 建设网站需要专业哪个企业提供电子商务网站建设外包
  • 公司网站建设及维护网站建设思维
  • 那个网站可以学做西餐17做网站广州沙河
  • 品牌网站建设哪里好京东网站建设案例
  • 亚马逊海外版网站深圳市工商注册信息查询网站
  • 新乐做网站优化网站上漂亮的甘特图是怎么做的
  • 新网站应该怎么做seo品牌推广方案思维导图
  • 想要网站导航推广页浅谈中兴电子商务网站建设
  • 免费引流在线推广成都网站优化费用
  • 老河口市网站佛山市点精网络科技有限公司
  • word模板免费网站seo引擎优化是做什么的
  • 办网站怎么赚钱鄠邑建站 网站建设
  • 宜春网站建设推广微信小程序开发
  • 巴南城乡建设网站免费网站建设软件大全
  • 湖南网站建设公公司没有自己的网站
  • 刚建设的网站如何推广网站恢复正常
  • 怎么做制作网站的教程永久免费空间免备案
  • 网站维护运营怎么做简单的手机网址大全
  • 网站建设规划设计公司排名使用模块化的网站
  • 南宁网站seo大概多少钱门户网站建设公司渠道
  • 如何建国际商城网站海门做网站公司
  • 做网站应该画什么图注册子公司流程及所需资料
  • 嵊州市建设银行网站怎么自己做游戏软件
  • 用模板快速建站中园建设银行网站
  • 网站建设罒金手指下拉壹陆韩国最新新闻消息
  • 东莞企业网站推广技巧wordpress怎么汉化