项目架构
- 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样式;
- APP:总布局
- routes:路由
- index.js:路由设置的文件,用于各种路由设置,插入到main.js中,然后插入到页面;
- 引入各个组件;
- index.js:路由设置的文件,用于各种路由设置,插入到main.js中,然后插入到页面;
- index.html:前端页面;
- main.js:入口文件,插入页面中的文件,用于引入各种资源,js模块,css文件;
- main-index.css:main.js中引入的css文件,用于替换引入的模块中的css样式,注意:必须设置在最下面;才能替换覆盖样式;
- assets:静态资源文件夹;
蚂蚁设计模块antd
- 下载模块
- 命令:
npm i --save antd
- 蚂蚁设计网站:Ant Design
- 命令:
- 在main.js中引入css文件;
- 代码:
import "antd/dist/antd.css"
- 代码:
- 使用menu导航菜单和Icon图标
- 引入模块,解构赋值:
import {Menu,Icon} from "antd"
- 分析:
-
标签为外围容器
-
标签为内部结构,需要设置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初始化的问题
- 代码:
- 引入模块,解构赋值:
字体Icon的引入
- 下载字体icon
- 在“Iconfont-阿里巴巴矢量图标库”上下载自己的字体图标;下载到本地,放在fonts文件夹中;
- 下载网站:Iconfont-阿里巴巴矢量图标库
- 参考文档:iconfont字体图标的使用方法
- 引入步骤:
- 将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"
:设置的
标签在页面中默认显示为span标签,则通过此设置为div标签; -
transitionName="appCom"
:用于设置css3过渡效果的css样式中,相对应的类名; -
transitionEnterTimeout={500} transitionLeaveTimeout={200}>
:用于设置过渡元素的进入和离开的所需时间,与css设置相对应; -
:为运动的元素,添加绝对定位;必须设置唯一的key值,否则会出错;{this.props.children} - 链接文档:React 附件动画API ReactCSSTransitionGroup
-
- 代码:
- App/index.js代码:
import ReactCSSTransitionGroup from "react-addons-css-transition-group" import "./index.css"
{this.props.children}- 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=(
- 引入到main.js中,插入index.html页面中代码:
import route from "./routes";//引入文件夹,就默认引入文件夹下的index.js文件; render(route,document.getElementById("app"));
链接
- node小项目实战
代码
- 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=(
);
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(
{this.props.children}
)
}
}
- 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=>(
{collapse?"":{item.msg}}
))
}
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(
{collapse?"":"果木山"}
)
}
}
简历项目实战复习
- 项目依赖
- antd:Layout布局 Menu导航菜单 Icon图标
- react-addons-css-transition-group:插件,给组件添加css3运动效果;
- [email protected]:固定版本,大于3.x的版本中History不能使用;
- 知识点:
- 使用Layout布局中的Menu组件时,要设置defaultSelectedKeys为变量,不能设置为定值,否则,页面刷新的时候,会默认加载设置的默认key值;
- 可以使用
this.props.location.pathname
来进行设置;
- 可以使用
- css3运动效果中,包裹的运动元素上的key值,必须是变量,否则没有动画效果,也可以通过
this.props.location.pathname
来设置; - 使用Layout布局中,会存在状态值collapsed,值为布尔值,可以通过布尔值的不同,来设置不同状态下的显示和隐藏;
- 使用Layout布局中的Menu组件时,要设置defaultSelectedKeys为变量,不能设置为定值,否则,页面刷新的时候,会默认加载设置的默认key值;
- 代码:
- 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=(
- 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(
{this.props.children}- 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 (
{collapsed?"":item.msg} ) }); return ( ) } } 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; }