用react完成一个个人简介页面

编程入门 行业动态 更新时间:2024-10-18 12:24:00

用react完成一个<a href=https://www.elefans.com/category/jswz/34/1744905.html style=个人简介页面"/>

用react完成一个个人简介页面

这虽然是一个简单的页面,但是在不断优化的过程中,我真真切切的体会到,一个页面完成它只是一个最最基本的事情,如何让你的代码利用率最高,复用性发挥到最大,让设计出来的组件真的只用来渲染数据而已,尽可能的减少if、else之类的判断,才是我们需要仔细体会研究的,

同时,我也深刻体会到react的首要思想:用组件件来开发应用的真正意义所在。

还有就是一个合理的数据结构能够帮助我们大大减少冗余的逻辑判断

接下来是我对几次优化的想法和心得体会的记录。

首先是scss文件,优化的过程中scss文件没有改变过:


/* rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推 *//* iPhone 6尺寸的根元素大小基准值 */$vm_fontsize: 75;@function rem($px) {@return ($px / $vm_fontsize ) * 0.5rem;}/* 根元素大小使用 vw 单位 */$vm_design: 750;html {font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw;/* 同时,通过Media Queries 限制根元素最大最小值 */@media screen and (max-width: 320px) {font-size: 64px; }@media screen and (min-width: 750px) {font-size: 150px;}}/*  body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小 */.MyInfo{min-width: 320px;max-width: 750px;margin: 0 auto;height:100%;font-size: rem(28);position: relative;}.about-me{background-color:gainsboro;height:rem(100);line-height: rem(100);padding-left: rem(20);}.textline{height:rem(100);line-height: rem(100);margin:0 rem(20);border-bottom: 1px solid gainsboro;}.col-line{display: inline-block;width:35%;}.col-input{width:50%;height:rem(40);border:none;}.col-select{display: inline-block;width:50%;color:rgb(102, 101, 101);font-size: rem(13);}.col-input:focus{outline: none;}.sel-divhide{display: none;}.sel-div{width:100%;height:100%;position: absolute;left:0;top:0;z-index: 100;background-color: rgba(223, 228, 231, 0.322);}.bottom{width: 100%;background-color: #fff;min-height:rem(100);position:absolute;bottom:0;left:0;z-index: 1000;}.top-style{margin:10px 0 10px 0;border-bottom:1px solid rgb(0, 204, 255);color:rgb(0, 204, 255);padding-bottom:rem(20);padding-left:rem(20);}.sel-div ul{padding-left:0px;}.li-style{margin:rem(10) rem(20);border-bottom:1px solid rgb(218, 221, 221);padding-bottom:rem(20);list-style: none;padding-left:rem(20);}.icon-class{width:rem(18);height:rem(18);vertical-align: baseline;margin-left:rem(30);}.sec-img{width:rem(25);height:rem(25);margin-right:rem(20);}.text-style{display: inline-block;vertical-align: top;}

然后是第一版的代码如下:


//MyInfo.jsimport React, { Component } from 'react';import './MyInfo.scss';import src from '../imges/right.png';import select from '../imges/select.png';// 数据const setting={sex:['男','女'],city:['广州','深圳','惠州','汕头'],school:['仲恺农业工程学院','广州大学','暨南大学','华南师范大学'],major:['软件工程','会计','物流管理','会展','市场营销']}class MyInfo extends Component {constructor(props){super(props)this.state={name:'',sex:'请选择',age:'',phone:'',city:'请选择',school:'请选择',major:'请选择',sel:false,mapArray:{}}}// 弹出对应类型的选择框selectSex=(e)=>{let sort=e.currentTarget.getAttribute("data-sort");let com;if(sort=='性别') com=setting.sex;else if(sort=='城市')com =setting.city;else if(sort=='学校')com=setting.school;else com=setting.major;let val={sort:sort,com:com}this.setState({sel:true,mapArray:val})}// 隐藏弹出的选择框hide=()=>{this.setState({sel:false});}// 选中选择框中的选项并返回结果selectCloumn=(e)=>{let sort=e.currentTarget.getAttribute("data-sort");let result=e.currentTarget.getAttribute("data-result");if(sort=='性别') this.setState({sel:false,sex:result});else if(sort=='城市')this.setState({sel:false,city:result})else if(sort=='学校')this.setState({sel:false,school:result})else this.setState({sel:false,major:result})}liItem=()=>{   const com = this.state.mapArray==undefined?[]:this.state.mapArray;const sort=this.state.mapArray.sort;let liItem= com.map((item,index)=>{return(<li key={index} className="li-style" data-sort={sort} data-result={item} onClick={this.selectCloumn}><img src={select} className="sec-img"></img><span className="text-style">{item}</span></li>)})return liItem;}render() {const com=this.state.mapArray==undefined?[]:this.state.mapArray;const sort=this.state.mapArray.sort;return (<div className='MyInfo'><div className='about-me'>个人简介</div><div className='textline'><span className='col-line'>姓名:</span><input  className='col-input' placeholder='请输入'/></div><div className='textline' data-sort='性别' onClick={this.selectSex}><span className='col-line'>性别:</span><span className="col-select">{this.state.sex}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline'><span className='col-line'>年龄:</span><input className='col-input' placeholder='请输入'/></div><div className='textline'><span className='col-line'>手机号码:</span><input className='col-input' placeholder='请输入'/></div><div className='textline' data-sort='城市' onClick={this.selectSex}><span className='col-line'>城市:</span><span className="col-select">{this.state.city}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' data-sort='学校' onClick={this.selectSex}><span className='col-line'>学校:</span><span className="col-select">{this.state.school}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' data-sort='专业' onClick={this.selectSex}><span className='col-line'>专业:</span><span className="col-select">{this.state.major}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div>{<div className={this.state.sel?"sel-div":"sel-divhide"} onClick={this.hide}>{/* 选择框 */}<div className="bottom"><div className="top-style">{sort}</div><ul>{this.liItem()}</ul></div></div>}</div>);}}export default MyInfo;

以上代码无疑功能是实现了的,但是无疑这段代码复用性很低,只能用来实现这个页面,其他地方无用武之地

优化的时候想着,弹出的选择框,如果其他地方需要,那么我把它封装成一个无状态组件,拿到数据我就渲染,这样子这一部分的复用性就大大提高了

于是修改后的代码如下:


//MyInfo.jsimport React, { Component } from 'react';import './MyInfo.scss';import src from '../imges/right.png';import SelectComponent from '../component/SelectComponent'// 数据const setting={sex:['男','女'],city:['广州','深圳','惠州','汕头'],school:['仲恺农业工程学院','广州大学','暨南大学','华南师范大学'],major:['软件工程','会计','物流管理','会展','市场营销']}class MyInfo extends Component {constructor(props){super(props)this.state={name:'',sex:'请选择',age:'',phone:'',city:'请选择',school:'请选择',major:'请选择',sel:false,mapArray:{}}}// 弹出对应类型的选择框selectSex=(e)=>{let sort=e.currentTarget.getAttribute("data-sort");let com;if(sort=='性别') com=setting.sex;else if(sort=='城市')com =setting.city;else if(sort=='学校')com=setting.school;else com=setting.major;let val={sort:sort,com:com}this.setState({sel:true,mapArray:val})}// 隐藏弹出的选择框hide=()=>{this.setState({sel:false});}// 选中选择框中的选项并返回结果selectCloumn=(sort,result)=>{if(sort=='性别') this.setState({sel:false,sex:result});else if(sort=='城市')this.setState({sel:false,city:result})else if(sort=='学校')this.setState({sel:false,school:result})else this.setState({sel:false,major:result})}render() {const com=this.state.mapArray==undefined?[]:this.state.mapArray;const sort=this.state.mapArray.sort;return (<div className='MyInfo'><div className='about-me'>个人简介</div><div className='textline'><span className='col-line'>姓名:</span><input  className='col-input' placeholder='请输入'/></div><div className='textline' data-sort='性别' onClick={this.selectSex}><span className='col-line'>性别:</span><span className="col-select">{this.state.sex}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline'><span className='col-line'>年龄:</span><input className='col-input' placeholder='请输入'/></div><div className='textline'><span className='col-line'>手机号码:</span><input className='col-input' placeholder='请输入'/></div><div className='textline' data-sort='城市' onClick={this.selectSex}><span className='col-line'>城市:</span><span className="col-select">{this.state.city}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' data-sort='学校' onClick={this.selectSex}><span className='col-line'>学校:</span><span className="col-select">{this.state.school}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' data-sort='专业' onClick={this.selectSex}><span className='col-line'>专业:</span><span className="col-select">{this.state.major}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div>{this.state.sel?<SelectComponent changecom={this.hide} sort={sort} com={com} selectCloumn={this.selectCloumn}></SelectComponent>:''}</div>);}}export default MyInfo;

封装的组件代码如下:


import React, { Component } from 'react';import select from '../imges/select.png'export default function SelectComponent(props){//    取出父组件传递过来的值let {sort,com,changecom,selectCloumn}=props;// 拿到选中的结果,并调用父组件中的selectCloumn事件把选择的结果呈现出来const getResult=(e)=>{let sortresult=e.currentTarget.getAttribute("data-sort");let resultArray=e.currentTarget.getAttribute("data-result");selectCloumn(sortresult,resultArray);}return(<div className="sel-div" onClick={changecom}><div className="bottom"><div className="top-style">{sort}</div><ul>{com.map((item,index)=>{return(<li key={index} className="li-style" data-sort={sort} data-result={item} onClick={getResult}><img src={select} className="sec-img"></img><span className="text-style">{item}</span></li>)})}</ul></div></div>)}

第二版的代码有了一定封装性和复用性,但是还是有问题的,我的函数对于每个选择框的识别都是通过传参和if-else的判断实现的,这些选择项数量的少的时候还好,但是如果有很多,无疑我这种判断方法是不利于代码维护的,

最好的模式应该是,每个标签的数据呈现都是直接读取就知道他是那个选项的就好了,于是我最后想到的是修改我原本的数据结构,只要在对象里面把我需要的信息定义好,那么我取对应的值得时候自然而然就知道他是谁了,

从而省去了一大堆的条件判断,也提高了性能。

于是第三版的代码如下:

import React, { Component } from 'react';import './MyInfo.scss';import src from '../imges/right.png';import SelectComponent from '../component/SelectComponent'// 数据const setting={sex:{val:"sex",sort:"性别",arr:['男','女'] },city:{val:"city",sort:"城市",arr:['广州','深圳','惠州','汕头']},school:{val:"school",sort:"学校",arr:['仲恺农业工程学院','广州大学','暨南大学','华南师范大学']},major:{val:"major",sort:"专业",arr:['软件工程','会计','物流管理','会展','市场营销']}}class MyInfo extends Component {constructor(props){super(props)this.state={name:'',sex:'请选择',age:'',phone:'',city:'请选择',school:'请选择',major:'请选择',mapArray:{},sel:false}}// 弹出对应类型的选择框selectSex=(res)=>{this.setState({sel:true,mapArray:setting[res]}) }// 选中选择框中的选项并返回结果selectCloumn=(sort,result)=>{this.setState({[sort]:result,sel:false})}render() {return (<div className='MyInfo'><div className='about-me'>个人简介</div><div className='textline'><span className='col-line'>姓名:</span><input  className='col-input' placeholder='请输入'/></div><div className='textline' onClick={this.selectSex.bind(this,'sex')}><span className='col-line'>性别:</span><span className="col-select">{this.state.sex}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline'><span className='col-line'>年龄:</span><input className='col-input' placeholder='请输入'/></div><div className='textline'><span className='col-line'>手机号码:</span><input className='col-input' placeholder='请输入'/></div><div className='textline' onClick={this.selectSex.bind(this,'city')}><span className='col-line'>城市:</span><span className="col-select">{this.state.city}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' onClick={this.selectSex.bind(this,'school')}><span className='col-line'>学校:</span><span className="col-select">{this.state.school}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><div className='textline' onClick={this.selectSex.bind(this,'major')}><span className='col-line'>专业:</span><span className="col-select">{this.state.major}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div><SelectComponent list={this.state.mapArray} selectCloumn={this.selectCloumn} sel={this.state.sel}></SelectComponent></div>);}}export default MyInfo;

封装组件的代码如下:

import React, { Component } from 'react';import select from '../imges/select.png'export default class MyInfo extends Component{constructor(props){super(props); this.state={sel:false}}// 拿到选中的结果,并调用父组件中的selectCloumn事件把选择的结果呈现出来getResult=(sortresult,resultArray)=>{this.setState({sel:false});this.props.selectCloumn(sortresult,resultArray);}// 隐藏弹出的选择框changecom=()=>{this.setState({sel:false});}//组件的props发生改变,在组件接收到一个新的prop时被执行。这个方法在初始化render时不会被调用。componentWillReceiveProps(nextProps) {if(nextProps.sel){this.setState({sel:true});}}render(){//    取出父组件传递过来的值let {list}=this.props;const arr=list.arr==undefined?[]:list.arr;const sort=list.sort;const val=list.val;return(<div className={this.state.sel?"sel-div":"sel-divhide"} onClick={this.changecom}><div className="bottom"><div className="top-style">{sort}</div><ul>{arr.map((item,index)=>{return(<li key={index} className="li-style" onClick={this.getResult.bind(this,val,item)}><img src={select} className="sec-img"></img><span className="text-style">{item}</span></li>)})}</ul></div>                           </div>)}}

第三版相对而言看起来就比较顺眼了,但是你会发现有一个地方很碍眼,也觉得不大友好,那就是个人简介的那些姓名年龄的标签,一大坨,但是实质上是

这个几个标签很相似,我们可以抽取它的共同点,把他们分成input和div两个标签,把他们放进封装组件,然后修改数据结构,通过数据来渲染他们就行;

代码如下:


//MyInfo.jsimport React, { Component } from 'react';import './MyInfo.scss';import SelectComponent from '../component/SelectComponent'// 数据const setting={page:"个人简介",init:[{val:"name",label:"input",sort:"姓名",value:"请输入"},{val:"sex",label:"select",sort:"性别",value:"请选择"},{val:"age",label:"input",sort:"年龄",value:"请输入"},{val:"phone",label:"input",sort:"手机号码",value:"请输入"},{val:"city",label:"select",sort:"城市",value:"请选择"},{val:"school",label:"select",sort:"大学",value:"请选择"},{val:"major",label:"select",sort:"专业",value:"请选择"},],select:{sex:{val:"sex",sort:"性别",arr:['男','女'] },city:{val:"city",sort:"城市",arr:['广州','深圳','惠州','汕头']},school:{val:"school",sort:"学校",arr:['仲恺农业工程学院','广州大学','暨南大学','华南师范大学']},major:{val:"major",sort:"专业",arr:['软件工程','会计','物流管理','会展','市场营销']}}}class MyInfo extends Component {render() {return (<div className='MyInfo'><SelectComponent setting={setting}></SelectComponent></div>);}}export default MyInfo;

组件代码如下:


import React, { Component } from 'react';import select from '../imges/select.png';import src from '../imges/right.png';export default class MyInfo extends Component{constructor(props){super(props)this.state={name:'',sex:'',age:'',phone:'',city:'',school:'',major:'',mapArray:{},sel:false,selectcolumn:{}}}// 弹出对应类型的选择框selectSex=(val)=>{this.setState({sel:true,mapArray:this.state.selectcolumn[val]})}// 拿到选中的结果,并调用父组件中的selectCloumn事件把选择的结果呈现出来getResult=(val,item)=>{this.setState({sel:false,[val]:item})}// 隐藏弹出的选择框changecom=()=>{this.setState({sel:false});}//  在dom加载之前把每一项的数值赋值给state中对应的sex,name等,方便选择框选择结果时的赋值componentWillMount(){this.props.setting.init.map((item)=>{let val=item.val;this.setState({[val]:item.value})}) this.setState({selectcolumn:this.props.setting.select})}render(){return(<div><div className='about-me'>{this.props.setting.page}</div>{this.props.setting.init.map((item)=>{if(item.label=="input")return(<div className='textline'><span className='col-line'>{item.sort}:</span><input  className='col-input' placeholder={item.value}/></div>)elsereturn(<div className='textline' onClick={this.selectSex.bind(this,item.val)}><span className='col-line'>{item.sort}:</span><span className="col-select">{this.state[item.val]}</span><span className='right-icon'><img src={src} className="icon-class"/></span></div> )                 })}{/* 弹出的选择框 */}{this.state.sel?   <div className="sel-div" onClick={this.changecom}><div className="bottom"><div className="top-style">{this.state.mapArray.sort}</div><ul>{this.state.mapArray.arr.map((item,index)=>{return(<li key={index} className="li-style" onClick={this.getResult.bind(this,this.state.mapArray.val,item)}><img src={select} className="sec-img"></img><span className="text-style">{item}</span></li>)})}</ul></div>                           </div>:''}</div>)}}

更多推荐

用react完成一个个人简介页面

本文发布于:2024-02-05 10:01:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1744756.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:个人简介   页面   react

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!