react搭建项目
1、创建react项目
使用react脚手架create-react-app
npm install -g create-react-app create-react-app my-app cd my-app npm start
使用yarn
yarn init
yarn add
yarn remove
yarn/yarn install
2、启动程序
yarn start
3、安装需要的库
首先安装路由以及less库
yarn add react-router-dom axios less-loader
3.1 暴露webpack配置文件
yarn eject
如果有报错
说明你之前改了配置,需要先暂存下
在VSCode的命令控制台输入
git add ./
git commit -m "init"
然后再执行yarn eject
package.json里出现了很多配置就说明暴露成功了
可以发现config里以及暴露了webpack的配置文件.dev是本地的开发配置,.prod是生成的配置,server是本地的server开发,使得本地开启3000端口服务器
3.2 配置less-loader
在dev文件里的 ‘test: /\.css$/,’前添加less-loader,并复制一份到prod配置里
{ test: /\.less$/, use: [ require.resolve('style-loader'), { loader: require.resolve('css-loader'), options: { importLoaders: 1, }, }, { loader: require.resolve('postcss-loader'), options: { // Necessary for external CSS imports to work // https://github.com/facebookincubator/create-react-app/issues/2677 ident: 'postcss', plugins: () => [ require('postcss-flexbugs-fixes'), autoprefixer({ browsers: [ '>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9', // React doesn't support IE8 anyway ], flexbox: 'no-2009', }), ], }, }, { loader:require.resolve('less-loader'), options: { modules: false, modifyVars: { "@primary-color": "#f9c700" //定制主题 } } } ], },
先通过less-loader去解析它,把他转换成能够识别的文件,再通过postcss-loader进去前缀的添加,最后转成css样式css-loader,再转成行内样式style-loader,一层一层往前转。
重新启动yarn start 后会报错Cannot find module 'less',
需要
yarn add less
3.3 安装antd
yarn add antd
使用前引入css样式
import 'antd/dist/antd.css';
还需要安装使用babel-plugin-import
babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件,比如该组件只使用了antd的Button组件,它就会只加载Button的css样式
在webpack.dev和webpack.prod的test: /\.(js|mjs|jsx)$/,里的options里加插件,用来按需加载antd的less文件
{ test: /\.(js|mjs|jsx)$/, include: paths.appSrc, loader: require.resolve('babel-loader'), options: { customize: require.resolve( 'babel-preset-react-app/webpack-overrides' ), plugins: [ [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-prettier,-svgo![path]', }, }, }, ],
], cacheDirectory: true, // Save disk space when time isn't as important cacheCompression: true, compact: true, }, },
配置好后,就不需要在任何地方通过import 'antd/dist/antd.css';引入样式了
但会报错
./node_modules/antd/lib/button/style/index.less Module build failed: // https://github.com/ant-design/ant-motion/issues/44 .bezierEasingMixin(); ^ Inline JavaScript is not enabled. Is it set in your options? in E:\webstrom\migu\ngoc\web\react-interface\react-interface-cli\node_modules\antd\lib\style\color\bezierEasing.less (line 110, column 0)
解决方法:
1.把 "style": true 改成 "style": 'css' 就好
['import', { libraryName: 'antd', style: 'css'}],
2.或者把 less 版本安装成2.7.3
yarn add less@^2.7.3
建议使用方法二解决,因为在前面配置less-loader的时候对antd定制了主题
{ loader:require.resolve('less-loader'), options: { modules: false, modifyVars: { "@primary-color": "#f9c700" //定制主题 } } }
方法一能加载antd的样式,是加载已经编译好的css文件,改不了变量,定制的主题会失效
3.4 jsonp(百度天气api用到)
之前已经安装了axios插件,但是只支持get和post请求,不支持跨域
yarn add jsonp --save
首先需要在百度天气api里获得ak值
getWeatherAPIData(){ let city = '北京'; axios.jsonp({ url:'http://api.map.baidu.com/telematics/v3/weather?location='+encodeURIComponent(city)+'&output=json&ak=3p49MVra6urFRGOT9s8UBWr2' }).then((res)=>{ if(res.status == 'success'){ let data = res.results[0].weather_data[0]; this.setState({ dayPictureUrl:data.dayPictureUrl, weather:data.weather }) } }) }
可通过https://www.npmjs.com/package/jsonp查看jsonp需要传的参数,
import JsonP from 'jsonp' export default class Axios { static jsonp(options) { return new Promise((resolve, reject) => { JsonP(options.url, { param: 'callback' }, function (err, response) { if (response.status == 'success') { resolve(response); } else { reject(response.messsage); } }) }) } }
<span className="weather-img"> <img src={this.state.dayPictureUrl} alt="" /> </span> <span className="weather-detail"> {this.state.weather} </span>
效果:
3.5 redux
yarn add redux --save
yarn add react-redux --save
步骤:
1.创建Action模块
2.创建 Reducer模块
3.创建Store模块
4.通过connect方法将React组件和Redux连接起来
5.添加Provider作为项目的根组件,用于数据的存储
安装中间键:
yarn add redux-thunk --save
redux调试工具安装
方法一:
1.首先,在Chrome中安装Redux Devtools扩展
2.
yarn add redux-devtools-extension
方法二:
yarn add redux-logger --save
在控制台直接输出action:
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import {Provider} from 'react-redux'; import {createStore, applyMiddleware} from 'redux'; import thunk from 'redux-thunk'; import createLogger from 'redux-logger'; import rootReducer from './redux/reducer'; import './index.css'; import Router from './router' import registerServiceWorker from './registerServiceWorker'; const middleware =[thunk, createLogger]; const store=createStore(rootReducer,applyMiddleware(...middleware)); ReactDOM.render( <Provider store={store}> <Router /> </Provider>, document.getElementById('root') ); registerServiceWorker();
reducer/index.js
import { combineReducers } from 'redux' import { type } from '../action'; const initialState = { menuName: '' } const ebikeData = (state=initialState, action) => { switch (action.type) { case type.SWITCH_MENU: return { ...state, menuName:action.menuName }; default: return {...state}; } }; export default ebikeData;
action/index.js
export const type = { SWITCH_MENU : 'SWITCH_MENU' } // 菜单点击切换,修改面包屑名称 export function switchMenu(menuName) { return { type:type.SWITCH_MENU, menuName } }
4、小技巧
4.1 建个default.less,存放颜色变量
@colorA: #f9c700;
4.2 计算宽高
height: calc(100vh);
height: calc(100%-64px);
4.3 将图片放入public文件夹的assets文件夹中,引入路径不需要加public
<img src="/assets/logo-ant.svg" alt=""/>
4.4 css实现箭头
一个正方形的盒子→把内容缩小,边框加粗→把内容弄没,盒子是实心的→把底边框去掉,只留上边框,左右边框→左右边框透明,上边框白色
.breadcrumb-title{ text-align: center; font-size: @fontC; &:after{ position: absolute; content: ''; left:73px; top:39px; border-top: 9px solid @colorM; border-left: 12px solid transparent; border-right: 12px solid transparent; } }
效果图
5、工具箱
5.1 获取系统时间并格式化
formateDate(time){ if(!time)return ''; let date = new Date(time); return date.getFullYear()+'-'+(date.getMonth()+1)+'-'+date.getDate()+' '+date.getHours()+':'+date.getMinutes()+':'+date.getSeconds(); }
传入当前系统的时间戳
setInterval(()=>{ let sysTime = Util.formateDate(new Date().getTime()); this.setState({ sysTime }) },1000)
显示:
5.2 隐藏手机号中间4位
formatPhone(phone) { phone += ''; return phone.replace(/(\d{3})\d*(\d{4})/g, '$1***$2') },
5.3 隐藏身份证号中11位
formatIdentity(number) { number += ''; return number.replace(/(\d{3})\d*(\d{4})/g, '$1***********$2') },