美文网首页React学习之路
react学习第四天笔记之简历项目

react学习第四天笔记之简历项目

作者: 果木山 | 来源:发表于2018-12-31 19:01 被阅读0次

    项目架构

    • src文件夹:开发时的源代码
      • assets:静态资源文件夹;
        • fonts:引入的icon字体图标文件;
        • css,js等静态资源文件
      • containers:容器型组件
        • About
        • Contact
        • Home
        • Project
        • Skill
      • layouts:布局
        • APP:总布局
          • index.js:总布局文件,用于设置页面的总布局结构;
          • index.css:用于设置自己的css样式;
        • Menu:导航栏布局
          • index.js:导航栏制作的布局,需要引入到APP中;
          • index.css:自己的css样式;
      • routes:路由
        • index.js:路由设置的文件,用于各种路由设置,插入到main.js中,然后插入到页面;
          • 引入各个组件;
      • index.html:前端页面;
      • main.js:入口文件,插入页面中的文件,用于引入各种资源,js模块,css文件;
      • main-index.css:main.js中引入的css文件,用于替换引入的模块中的css样式,注意:必须设置在最下面;才能替换覆盖样式;

    蚂蚁设计模块antd

    • 下载模块
      • 命令:npm i --save antd
      • 蚂蚁设计网站:Ant Design
    • 在main.js中引入css文件;
      • 代码:import "antd/dist/antd.css"
    • 使用menu导航菜单和Icon图标
      • 引入模块,解构赋值:import {Menu,Icon} from "antd"
      • 分析:
        • <Menu>..</Menu>标签为外围容器
        • <Menu.Item>..</Menu.Item>标签为内部结构,需要设置key,为唯一值;
        • defaultSelectedKeys={["home"]}:指的是默认选中key设置为home的元素;
        • mode="inline":指的是内联列表
        • theme="dark":指的是主题为dark;
      • 注意:在设置默认的key时,必须设置与当前地址相同的那一项,如果赋值为定值,则页面刷新后,会默认再指向默认值对应的那项,可以通过父级的this.props.location.pathname来获取地址,然后自定义属性传给子级MenuList,再设置在defaultSelectedKeys中;
      • 问题:页面刷新后,menu会默认点亮设置的defaultSelectedKeys对应的keys值,所以需要在页面刷新后,重新设置新的值;
      • 方法:设置state值,在钩子函数中获取pathname值,再更新state值,进而设置新的defaultSelectedKeys值;参考链接:React 中使用antd,刷新时被选中的menu初始化的问题
      • 代码:
       <Menu
           defaultSelectedKeys={["home"]}
           mode="inline"
           theme="dark"
       >
           <Menu.Item key={item.path}>
               <Link to={item.path==="home"?"/":item.path}>
                   <i className={"iconn icon iconfont "+item.icon}/>
                   {collapse?"":<span className="msg">{item.msg}</span>}
               </Link>
           </Menu.Item>
       </Menu>
      

    字体Icon的引入

    • 下载字体icon
    • 引入步骤:
      • 将fonts文件夹放在assets文件夹下;
      • 在main.js主体文件下,引入iconfont.css文件;
      • 通过class名来引入icon图标;类名可以参考demo_fontclass.html文件;
      • 配置webpack.config.js中的module;(需要下载url-loader,file-loader模块)
       module:{
           rules:[
               {//配置字体;
                   test:/\.(eot|svg|ttf|woff)(\?\w*)?$/,
                   use:"url-loader?limit=50000"
               },
               {//配置图片
                   test:/\.(png|git|jpg|jepg)$/,
                   use:"url-loader?limit=50000"
               }
           ]
       }
      

    让模块有css3的运动效果

    • 需要的插件:react-addons-css-transition-group
    • 注意事项:
      • 下载插件,并且引入插件;
      • 让谁动,就把插件包裹在谁的外面;注意不要影响页面的大结构
      • 配置好react-addons-css-transition-group
      • 添加定位:ReactCSSTransitionGroup设置相对定位,需要运动的元素设置绝对定位;
      • 设置css:把example改成我们设置的名字;同时写入动画;
      • js文件中,要运动的标签名上必须有key,key是唯一的,即使只有一个元素动,也要设置key,key必须设置;
      • 设置key时,可以设置this.props.location.pathname值;
    • ReactCSSTransitionGroup设置参数分析:
      • className="appCompo":设置class类名,用于设置自己的样式;需要设置相对定位;
      • component="div":设置的<ReactCSSTransitionGroup>标签在页面中默认显示为span标签,则通过此设置为div标签;
      • transitionName="appCom":用于设置css3过渡效果的css样式中,相对应的类名;
      • transitionEnterTimeout={500} transitionLeaveTimeout={200}>:用于设置过渡元素的进入和离开的所需时间,与css设置相对应;
      • <div className="appCompoInner" key={this.props.location.pathname}> {this.props.children} </div>:为运动的元素,添加绝对定位;必须设置唯一的key值,否则会出错;
      • 链接文档:React 附件动画API ReactCSSTransitionGroup
    • 代码:
      • App/index.js代码:
       import ReactCSSTransitionGroup from "react-addons-css-transition-group"
       import "./index.css"
       <div className={collapse?"appWrap-container appWrap-container-collapse":"appWrap-container"}>
           <ReactCSSTransitionGroup
               className="appCompo"
               component="div"
               transitionName="appCom"
               transitionEnterTimeout={500}
               transitionLeaveTimeout={200}>
               <div className="appCompoInner" key={this.props.location.pathname}>
                   {this.props.children}
               </div>
           </ReactCSSTransitionGroup>
       </div>
      
      • App/index.css代码:
       /*css3过渡效果代码*/
       .appCompo{
          position: relative;
          height: 100%;
          width: 100%;
       }
      
       .appCompo .appCompoInner{
           position: absolute;
           width: 100%;
       }
      
       .appCom-enter {
           opacity: 0.01;
           transform: translate3d(100%,0,0);
       }
       
       .appCom-enter.appCom-enter-active {
           opacity: 1;
           transform: translate3d(0,0,0);
           transition: all 500ms ease-in;
       }
       
       .appCom-leave {
           opacity: 1;
       }
       
       .appCom-leave.appCom-leave-active {
           opacity: 0.01;
           transition: all 200ms ease-in;
       }
      

    折叠菜单的效果

    • 知识:
      • 通过设置App自身的state状态,来控制元素不同类名的设置;
      • 父级组件App设置state状态下的collapse属性,通过条件判断来控制元素不同类名的设置,进而显示不同的效果;
      • 父级组件的collapse值,通过给子组件MenuList设置自定义属性,传给子组件MenuList
      • 子组件通过this.props来获取父级传来的数据;
      • 子组件传递数据给父组件:子组件中通过点击事件来控制父组件state状态下的collapse值的改变;
        • 父组件设置函数changeCollapse,函数内设置state的状态;在MenuList标签上设置自定义属性将函数体传递给子组件,注意:保证函数体内的this为实例,此处使用的是箭头函数创建函数;也可以使用bind
        • 子组件通过this.props获取到父组件传递的函数体,然后赋给点击事件;当点击事件触发时,执行函数,父组件state状态改变;

    知识点

    • 如果文件夹下,存在index.js文件,当通过import引入时,引入文件夹,即默认引入文件夹下的index.js文件;
      • import MenuList from "../Menu";指的是引入文件夹Menu下的index.js文件;
    • this.props.loaction.pathname可以获取路由地址;
    • 创建route时,可以通过变量创建,导出时,导出变量名即可,引入到其他组件中使用时,不是标签,而是变量
      • 代码:
       const route=(
           <Router history={browserHistory}>
               <Route path="/" component={App}>
                   <IndexRoute component={Home}/>
                   <Route path="/about" component={About}/>
                   <Route path="/contact" component={Contact}/>
                   <Route path="/project" component={Project}/>
                   <Route path="/skill" component={Skill}/>
               </Route>
           </Router>
       );
       export default route;
      
      • 引入到main.js中,插入index.html页面中代码:
       import route from "./routes";//引入文件夹,就默认引入文件夹下的index.js文件;
       render(route,document.getElementById("app"));
      

    简书链接

    代码

    • webpack.config.js代码
     const webpack=require("webpack");
     const path=require("path");
     const HtmlWebpackPlugin=require("html-webpack-plugin");
     const ExtractWebpackPlugin=require("extract-text-webpack-plugin");
     
     module.exports={
         entry:path.resolve(__dirname,"src/main.js"),
         output:{
             path:path.resolve(__dirname,"dist"),
             filename:"my-third-bundle.js"
         },
         module:{
             rules:[
                 {
                     test:/\.js(x)?$/,
                     use:"babel-loader",
                     exclude:/node_modules/
                 },
                 {
                     test:/\.css$/,
                     use:ExtractWebpackPlugin.extract({
                         fallback:"style-loader",
                         use:"css-loader"
                     })
                 },
                 {
                     test:/\.(eot|svg|ttf|woff)(\?\w*)?$/,
                     use:"url-loader?limit=50000"
                 },
                 {
                     test:/\.(png|git|jpg|jepg)$/,
                     use:"url-loader?limit=50000"
                 }
             ]
         },
         devServer: {
             disableHostCheck: true, //  新增该配置项,防止浏览器控制台报错;
         },
         plugins:[
             new ExtractWebpackPlugin({
                filename:"style.css"
             }),
             new HtmlWebpackPlugin({
                 template:path.resolve(__dirname,"src/Index.html")
             })
         ],
         mode:"development"
     };
    
    • package.json代码
     {
       "name": "day4",
       "version": "1.0.0",
       "description": "",
       "main": "index.js",
       "scripts": {
         "test": "echo \"Error: no test specified\" && exit 1",
         "start": "webpack-dev-server --progress --colors --content-base dist --history-api-fallback",
         "build": "webpack --progress --colors"
       },
       "keywords": [],
       "author": "guomushan",
       "license": "ISC",
       "devDependencies": {
         "babel-cli": "^6.26.0",
         "babel-core": "^6.26.3",
         "babel-loader": "^7.1.5",
         "babel-preset-es2015": "^6.24.1",
         "babel-preset-react": "^6.24.1",
         "babel-preset-stage-0": "^6.24.1",
         "css-loader": "^2.1.0",
         "extract-text-webpack-plugin": "^4.0.0-beta.0",
         "html-webpack-plugin": "^3.2.0",
         "prop-types": "^15.6.2",
         "react-addons-css-transition-group": "^15.6.2",
         "style-loader": "^0.23.1",
         "url-loader": "^1.1.2",
         "webpack": "^4.28.3",
         "webpack-cli": "^3.1.2",
         "webpack-dev-server": "^3.1.14"
       },
       "dependencies": {
         "antd": "^3.11.6",
         "react": "^16.7.0",
         "react-dom": "^16.7.0",
         "react-router": "^3.0.5"
       }
     }
    
    
    • main.js代码
     import React,{Component} from "react";
     import ReactDom,{render} from "react-dom";
     
     import route from "./routes";//引入文件夹,就默认引入文件夹下的index.js文件;
     //引入蚂蚁设计的css样式;
     import "antd/dist/antd.css"
     //引入字体图标的css
     import "./assets/fonts/iconfont.css";
     //引入自己的css样式,用于覆盖其他样式
     import "./main-index.css";
     
     render(route,document.getElementById("app"));
    
    • routes-index.js代码
     //路由设置
     import React,{Component} from "react";
     import {Router,Route,browserHistory,IndexRoute} from "react-router";
     
     import App from "../layouts/App";
     import Home from "../containers/Home";
     import About from "../containers/About";
     import Contact from "../containers/Contact";
     import Project from "../containers/Project";
     import Skill from "../containers/Skill";
     
     const route=(
         <Router history={browserHistory}>
             <Route path="/" component={App}>
                 <IndexRoute component={Home}/>
                 <Route path="/about" component={About}/>
                 <Route path="/contact" component={Contact}/>
                 <Route path="/project" component={Project}/>
                 <Route path="/skill" component={Skill}/>
             </Route>
         </Router>
     );
     export default route;
    
    • layouts-App-index.js代码
     import React,{Component} from "react";
     import {Link,IndexLink} from "react-router";
     import ReactCSSTransitionGroup from "react-addons-css-transition-group"
     
     import MenuList from "../Menu";
     
     import "./index.css"
     
     export default class App extends Component{
         constructor(){
             super();
             this.state={
                 collapse:true
             }
         }
         //箭头函数保证this指向;
         changeCollapse=()=>{
             this.setState({
                 collapse:!this.state.collapse
             })
         };
         render(){
             var {collapse}=this.state;//解构赋值
             return(
                 <div className="appWrap">
                     <div className={collapse?"appWrap-menu appWrap-menu-collapse":"appWrap-menu"}>
                         <MenuList collapse={collapse} changeCollapse={this.changeCollapse}/>
                     </div>
                     <div className={collapse?"appWrap-container appWrap-container-collapse":"appWrap-container"}>
                         <ReactCSSTransitionGroup
                             className="appCompo"
                             component="div"
                             transitionName="appCom"
                             transitionEnterTimeout={500}
                             transitionLeaveTimeout={200}>
                             <div className="appCompoInner" key={this.props.location.pathname}>
                                 {this.props.children}
                             </div>
                         </ReactCSSTransitionGroup>
                     </div>
                 </div>
             )
         }
     }
    
    • layouts-Menu-index.js代码
     import React,{Component} from "react";
     import {Link} from "react-router";
     import {Menu,Icon} from "antd"
     
     import "./index.css"
     export default class MenuList extends Component{
         showMenuItem(data){
             var {collapse}=this.props;
             //遍历数据data,箭头函数匿名函数的模式 p=>(),其中p为形参;
             return data.map(item=>(
                 <Menu.Item key={item.path}>
                     <Link to={item.path==="home"?"/":item.path}>
                         <i className={"iconn icon iconfont "+item.icon}/>
                         {collapse?"":<span className="msg">{item.msg}</span>}
                     </Link>
                 </Menu.Item>
             ))
         }
         render(){
             var {collapse,changeCollapse}=this.props;
             var data=[
                 {"path":"home","msg":"首页","icon":"icon-home"},
                 {"path":"about","msg":"关于我","icon":"icon-guanyuwomen"},
                 {"path":"project","msg":"技能知识","icon":"icon-zhuanyezhishijineng"},
                 {"path":"skill","msg":"项目经验","icon":"icon-xiangmu"},
                 {"path":"contact","msg":"联系我们","icon":"icon-lianxiwomen"}
             ];
             return(
                 <div className="menu">
                     <p className={collapse?"menu-user menu-user-collapse":"menu-user"}><Icon type="codepen-circle"/><span>{collapse?"":"果木山"}</span></p>
                     <Menu
                         defaultSelectedKeys={["home"]}
                         mode="inline"
                         theme="dark"
                     >
                         {this.showMenuItem(data)}
                     </Menu>
                     <span className="jian" onClick={changeCollapse}><Icon type={collapse?"right":"left"}/></span>
                 </div>
             )
         }
     }
    

    简历项目实战复习

    • 项目依赖
      • antd:Layout布局 Menu导航菜单 Icon图标
      • react-addons-css-transition-group:插件,给组件添加css3运动效果;
      • react-router@3.x:固定版本,大于3.x的版本中History不能使用;
    • 知识点:
      • 使用Layout布局中的Menu组件时,要设置defaultSelectedKeys为变量,不能设置为定值,否则,页面刷新的时候,会默认加载设置的默认key值;
        • 可以使用this.props.location.pathname来进行设置;
      • css3运动效果中,包裹的运动元素上的key值,必须是变量,否则没有动画效果,也可以通过this.props.location.pathname来设置;
      • 使用Layout布局中,会存在状态值collapsed,值为布尔值,可以通过布尔值的不同,来设置不同状态下的显示和隐藏;
    • 代码:
      • main.js代码:
       //引入模块
       import React from "react";
       import ReactDom,{render} from "react-dom";
       
       //引入antd的样式
       import "antd/dist/antd.css";
       
       //引入iconfont样式
       import "./assets/icon/iconfont.css";
       
       //引入自己的样式
       import "./index.css";
       
       //引入路由route
       import routes from "./routes";
       
       //渲染页面
       render(routes,document.getElementById("app"));
      
      • routes代码:
       //路由设置
       import React,{Component} from "react";
       
       import {Router,Route,browserHistory,IndexRoute} from "react-router";
       
       import App from "../layouts/App";
       import Home from "../containers/Home";
       import Contact from "../containers/Contact";
       import Project from "../containers/Project";
       import Skill from "../containers/Skill";
       import About from "../containers/About";
       
       const route=(
           <Router history={browserHistory}>
               <Route path="/" component={App}>
                   <IndexRoute component={Home}/>
                   <Route path="/contact" component={Contact}/>
                   <Route path="/project" component={Project}/>
                   <Route path="/skill" component={Skill}/>
                   <Route path="/about" component={About}/>
               </Route>
           </Router>
       );
       export default route;
      
      • App代码:
        • index.js:
         import React from "react";
         
         //引入antd模块
         import { Layout} from 'antd';
         
         const { Content, Sider } = Layout;
         
         //引入动画组件react-addons-css-transition-group
         import ReactCSSTransitionGroup from "react-addons-css-transition-group";
         
         //引入自定义模块
         import MenuList from "../Menu";
         
         import "./index.css"
         
         class App extends React.Component{
             state = {
                 collapsed: false,
                 pathname: "",
             };
         
             onCollapse = collapsed => {
                 this.setState({ collapsed });
             };
             UNSAFE_componentWillMount(){
                 this.setState({
                     pathname: this.props.location.pathname
                 })
             }
             render(){
                 return(
                     <Layout style={{ minHeight: '100vh'}}>
                         <Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse} collapsedWidth={80}>
                             <div className="logo"/>
                             <MenuList collapsed={this.state.collapsed} pathname={this.state.pathname}/>
                         </Sider>
                         <Layout>
                             <Content style={{ margin: '16px',backgroundColor: 'lavenderblush'}}>
                                 <ReactCSSTransitionGroup
                                     className="appCompo"
                                     component="div"
                                     transitionName="appCom"
                                     transitionEnterTimeout={500}
                                     transitionLeaveTimeout={200}
                                 >
                                     <div className="appCompoInner" key={this.props.location.pathname}>
                                         {this.props.children}
                                     </div>
                                 </ReactCSSTransitionGroup>
                             </Content>
                         </Layout>
                     </Layout>
                 )
             }
         }
         export default App;
        
        • index.css:
         #app .logo {
             height: 32px;
             background: rgba(255, 255, 255, 0.2);
             margin: 16px;
         }
         /*css3过渡效果代码*/
         .appCompo{
             position: relative;
             height: 100%;
             width: 100%;
         }
         .appCompo .appCompoInner{
             position: absolute;
             width: 100%;
             height: 100%;
             padding: 24px;
         }
         .appCom-enter {
             opacity: 0.01;
             transform: translate3d(80%,0,0);
         }
         
         .appCom-enter.appCom-enter-active {
             opacity: 1;
             transform: translate3d(0,0,0);
             transition: all 500ms ease-in;
         }
         
         .appCom-leave {
             opacity: 1;
         }
         
         .appCom-leave.appCom-leave-active {
             opacity: 0.01;
             transition: all 200ms ease-in;
         }
        
      • Menu代码:
        • index.js:
         import React,{Children} from "react";
         import {Link} from "react-router";
         
         //引入antd模块
         import { Menu, Icon } from 'antd';
         const { SubMenu } = Menu;
         
         //引入样式
         import "./index.css";
         
         class Menus extends React.Component{
             constructor(){
                 super();
                 this.state={
                     defaultSelectedKeys: ["home"]
                 }
             }
             UNSAFE_componentWillMount(){
                 //在钩子函数中获取数据;此处本地设置参数;实际开发中从服务器端获取数据
                 this.data=[
                     {"path":"home","msg":"首页","icon":"icon-my-home"},
                     {"path":"about","msg":"关于我","icon":"icon-dianhua"},
                     {"path":"project","msg":"技能知识","icon":"icon-gongrenjinengshujuku"},
                     {"path":"skill","msg":"项目经验","icon":"icon-gouwuche"},
                     {"path":"contact","msg":"联系我们","icon":"icon-dianhua"}
                 ];
                 //设置menu的默认选中keys
                 var pathname=this.props.pathname;
                 if(pathname==="/"){
                     pathname="/home"
                 }
                 pathname=pathname.split("/")[1];
                 this.setState({
                     defaultSelectedKeys: [pathname]
                 })
             }
             render(){
                 //解构赋值
                 var {collapsed}=this.props;
                 //返回插入数据的标签
                 let MenuItem=this.data.map((item)=>{
                     return (
                         <Menu.Item key={item.path} style={{fontSize: "16px"}}>
                             <Link to={item.path==="home"?("/"):("/"+item.path)}>
                                 <i className={"iconfont "+item.icon}></i>
                                 <span style={{marginLeft: "10px"}}>{collapsed?"":item.msg}</span>
                             </Link>
                         </Menu.Item>
                     )
                 });
                 return (
                     <Menu theme="dark" defaultSelectedKeys={this.state.defaultSelectedKeys} mode="inline">
                         {MenuItem}
                     </Menu>
                 )
             }
         }
         
         export default Menus;
        
        • index.css:
         .ant-menu-item .anticon, .ant-menu-submenu-title .anticon{
             font-size: 16px;
         }
         .ant-menu-inline-collapsed > .ant-menu-item .anticon, .ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-item .anticon, .ant-menu-inline-collapsed > .ant-menu-item-group > .ant-menu-item-group-list > .ant-menu-submenu > .ant-menu-submenu-title .anticon, .ant-menu-inline-collapsed > .ant-menu-submenu > .ant-menu-submenu-title .anticon{
             font-size: 16px;
         }
        

    相关文章

      网友评论

        本文标题:react学习第四天笔记之简历项目

        本文链接:https://www.haomeiwen.com/subject/ozewlqtx.html