react项目整理(react基础+react全家桶+ant-ui知识)基础篇(四)
项目中使用的功能方法请求外部的百度地图下的天气API先在百度地图开放平台,创建应用,选择浏览器,生成自己的AK码在代码中安装jsonpsudo yarn add jsonp --save封装jsonp方法import JsonP from ‘jsonp’export default class Axios {// 链式调用static jsonp (options) {return new Pro
项目中使用的功能方法
- 请求外部的百度地图下的天气API
先在百度地图开放平台,创建应用,选择浏览器,生成自己的AK码
在代码中安装jsonp
sudo yarn add jsonp --save
封装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); // 失败回调
}
})
})
}
}
在组件中调用
import axios from '../../axios'
state={}
componentWillMount () {
this.getWeatherAPIData() // 调用方法
}
// 获取天气api,encodeURIComponent编码对中文的处理
getWeatherAPIData () {
let city = '北京'
axios.jsonp({
url: 'http://api.map.baidu.com/telematics/v3/weather?location='+encodeURIComponent(city)+'&output=json&ak=3p49MVra6urFRGOT9s8UBWr2' // api地址 , ak是你自己申请的应用ak
}).then((res) => {
if(res.status == 'success'){
let data = res.results[0].weather_data[0]; // 取当前的天气
this.setState({
dayPictureUrl:data.dayPictureUrl,
weather:data.weather
})
}
})
}
// 在render中渲染
<span className="weather-img">
<img src={this.state.dayPictureUrl} alt="" />
</span>
<span className="weather-detail">
{this.state.weather}
</span>
2.react-router4.0(不需要路由配置,一切皆组件,浏览器端)
核心用法:
HashRouter和BrowserRouter
hash: http://localhost:3000/#/admin
browser: http://localhost:3000/admin
2.Route:path,exact,component,render — 参考项目中的pages下的router-demo下的router2文件夹的内容
<Router>
<Home> // home 是主界面,包含的都是他的子组件路由
<Route path="/" component={Main} exact></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</Home>
</Router>
主界面加载子组件的地方,添加{this.props.children}
3.NavLink,Link ------ 通过this.props.match接受路由带的内容— 参考项目中的pages下的router-demo下的router1文件夹的内容
<HashRouter>
{/* 需要根节点 */}
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
{/* /about会检索到/和/about,所以防止加载两次,加上exact精确匹配 */}
<Route path="/" component={Main}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</div>
</HashRouter>
4.Switch
<Switch>
{/* switch只会加载一次,按顺序 */}
<Route path="/" component={Main}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</Switch>
5.Redict
<Redirect to="/admin/home" />
withRouter 直接跳转路由
import {withRouter} from 'react-router-dom' 引入
使用
this.props.history.push({
pathname: '/admin'
})
渲染,在export default 中增添
withRouter(Form.create()(OrganizeManage))
3.项目中运用router实现菜单导航路由
根路由的编写
在src目录下建立router.js文件 , 并在全局index.js中更换Router
在router.js中引用app.js作为主框架
import React from 'react'
import {HashRouter, Route, Switch} from 'react-router-dom'
import App from './App'
import Login from './pages/login'
import Admin from './admin'
export default class IRouter extends React.Component{
render () {
return (
<HashRouter>
<App>
<Route path="/login" component={Login}/> (一级路由--登录界面)
<Route path="/admin" component={Admin}/> (一级路由--登录进来的页面)
</App>
</HashRouter>
)
}
}
在app中引用子路由
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
}
export default App;
在一级路由下嵌套二级路由,更改的admin界面下的路由配置
<Route path="/admin" render={() =>
// 二级路由
<Admin>
<Route path="/admin/ui/button" component={Button}/>
</Admin>
}/>
在admin.js中更改
<Row className="content" >
{this.props.children} // 这里引用
</Row>
菜单路由link配置
引用路由 在NavLeft页面下
import {NavLink} from 'react-router-dom'
在menu-item中包裹路由
<Menu.Item title={item.title} key={item.key}>
<NavLink to={item.key}>{item.title}</NavLink> // 这里跳转地址
</Menu.Item>
配置路由加载错误的情况下的展示页面
先建立文件夹nomatch包裹404展示文件,再在路由里面引用
<Switch>
<Route path="/admin/ui/buttons" component={Buttons}/>
<Route component={NoMatch}></Route>
</Switch>
Ant design UI组件的基本使用
在项目地址下的ui文件夹有基本的使用展示,你可以选择clone我的项目下到本地进行查看,接下来的笔记介绍几种初学者会遇到的使用
-
form组件实现登录
创建用户名和密码以及登录摁钮需要引用FormItem
const FormItem = Form.item
<Form>
<FromItem>
<Input prefix={<Icon type="user" />} placeholder="请输入用户名"/>
</FormItem>
<FromItem>
<Input prefix={<Icon type="lock" />} placeholder="请输入密码"/>
</FormItem>
<FromItem>
<Button type="primary">登录</Button>
</FormItem>
</Form>
添加输入验证
第一步:在render中创建getFieldDecorator对象
const { getFieldDecorator } = this.props.form;
第二步:给标签内嵌入js语法实现验证
<FormItem>
{
getFieldDecorator('userName',{ // username是定义的用户名变量,不同输入框的命名要是分别的
initialValue:'',
rules:[
{
required:true,
message:'用户名不能为空'
},
{
min:5,max:10,
message:'长度不在范围内'
},
{
pattern:new RegExp('^\\w+$','g'), // 正则表达式都可以
message:'用户名必须为字母或者数字'
}
]
})(
<Input prefix={<Icon type="user"/>} placeholder="请输入用户名" />
)
}
</FormItem>
第三步:通过Form创建表单
class FormLogin extends React.Component 将前面的export default 去掉
export default Form.create()(FormLogin); 在结尾中加入
添加摁钮点击校验
第一步: 给摁钮绑定事件
<Button type="primary" onClick={this.handleSubmit}>登录</Button>
第二步:编写事件
handleSubmit = ()=>{
let userInfo = this.props.form.getFieldsValue();
this.props.form.validateFields((err,values)=>{
if(!err){ // 如果没有错的情况下
message.success(`${userInfo.userName} 恭喜你,您通过本次表单组件学习,当前密码为:${userInfo.userPwd}`)
}
})
}
- datePicker日期控件的引用
想要设置默认值,需要引用moment插件
sudo yarn add moment --save
import moment from 'moment
<FormItem label="生日" >
{
getFieldDecorator('birth', {
initialValue: moment('2018-08-08') , // 获取moment
rules: [
{
required: true
}
]
})(
<DatePicker
showTime
format="YYYY-MM-DD"
/>
)
}
</FormItem>
3.栅格左右大小分配格式提取
const formItemLayout = { // 栅格样式 复用
labelCol: {
xs: 24,
sm: 4
},
wrapperCol: {
xs: 24,
sm: 8
}
}
<FormItem {... formItemLayout}> 使用es6结构赋值
</FormItem>
4.上传文件
<Upload
listType="picture-card"
howUploadList={false}
// axtion是服务器的地址
action="//jsonplaceholder.typicode.com/posts/"
nChange={this.handleChange}
>
{this.state.userImg?<img src={this.state.userImg} />:<Icon type="plus"></Icon>}
</Upload>
handleChange = (info) => { // 上传图像
if (info.file.status === 'uploading') {
this.setState({ loading: true });
return;
}
if (info.file.status === 'done') {
// 正常是调用服务器的上传地址
}
}
- easy mock,语法参考mock.js
是一款可以适用于前端编写线上接口,以便测试调用,自动创建项目,编写接口,放入数据
' result|10': [ { // 生成十条数据
"code": 0,
"message": '失败',
"result|10": [{
'id|+1': 0, // 递增+1
'userName': '@cname', // 随机的名字
'sex|1-2': 1, // 随机在1-2中选择
'telephone': '888888',
'state|1-5': 1,// 随机在1-5中选择
'interest|1-8': 1,// 随机在1-8中选择
'birth': '1995-06-30',
'address': '地球',
}]
- axios使用与封装
最简单的引用
// 动态获取mock数据,根据上步创建的接口获取
import axios from 'axios
request = () => {
let baseUrl = 'https://www.easy-mock.com/mock/5caffee40ee3ff114ba3e62b/yxjapi'
axios.get(`${baseUrl}/table/list`).then((res) =>{
if (res.data.code == '0') {
this.setState({
dataSource2: res.data.result
})
}
})
}
封装axios请求
static ajax(options){
const baseURL = 'https://www.easy-mock.com/mock/5caffee40ee3ff114ba3e62b/yxjapi' // 接口地址
return new Promise((resolve,reject) => {
axios({
url: options.url,
method: 'get',
baseURL: baseURL,
timeout: 7000,
params: (options.data.params && options.data) || ''
}).then((response) => {
if (response.status == '200') {// http请求自带status
let res = response.data
if (res.code == '0') { // 项目服务器后台接口业务层面的判断
resolve(res)
}else {
Modal.info({
title: '提示',
content: res.data.messsage
})
}
}else {
reject(response.data)
}
})
})
}
使用
axios.ajax({
url: '/table/list',
data: {
params: {
page: 1
}
}
}).then((res) => {
if (res.code == '0') {
this.setState({
dataSource2: res.result
})
}
})
- 表格分页的封装
// 分页的封装
pagination (data, callback) {
let page = {
onChange: (current) => {
callback(current)
},
current: data.result.page,
pageSize: data.result.page_size,
total: data.result.total,
showTotal: () => {
return `共${data.result.total}条`
},
showQuickJumper: true
}
return page
}
使用
request = () => {
axios.ajax({
url: '/table/list',
data: {
params: {
page: 1
},
isShowLoading: true
}
}).then((res) => {
if (res.code == '0') {
this.setState({
dataSource2: res.result.list,
selectedRowKeys: [], // 删除后的重置
selectedRows: null, // 删除后的重置
pagination: util.pagination(res, (current)=>{ // 根据点击的页玛进行数据变化处理
// to-do
_this.params.page = current
_this.request()
message.success(`当前页${current}`)
})
})
}
})
<Table
bordered
dataSource={this.state.dataSource2}
columns={columns}
pagination={this.state.pagination}
/>
8 . 组件使用外部class的form表单,获取表单对象
绑定wrappedComponentRef方法输出表达对象给dataform自定义,通过
let drgInfo = this.dataForm.props.form.getFieldsValue() 获取数据
<OpenFormDatas wrappedComponentRef={(datas) => {this.dataForm = datas}} />
- 地图功能的实现(基于项目中的骑车路线)
创建ak,加载百度地图sdk
地图初始化,添加地图控件
绘制路线(通过坐标点)
绘制服务区地图
(1) 创建ak,加载百度地图sdk
第一步:打开map.baidu.com,找到地图开放平台,点击进入
第二步:点击开发文档,点击web开发下的JavaScript API
第三步:在产品简介中,点击申请秘钥ak,创建应用,选择浏览器 端,白名单中设置*号,点击创建即可获取ak值
第四步:在public文件夹下的index.html的head部分中引用以下代码
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的ak秘钥"></script>
(2)初始化地图
第一步:创建一个渲染地图的容器,取一个id值
<div id="orderDetailMap" className="order-map"></div>
第二步:为获取地图对象添加方法,并且添加控件,同时在接口数据返回后调用方法
renderMap = (result)=>{
this.map = new window.BMap.Map('orderDetailMap');
// 添加地图控件
this.map.centerAndZoom('北京',11); // 设置地图的中心点
this.addMapControl();
}
// 添加地图控件
addMapControl = ()=>{
let map = this.map;
map.addControl(new window.BMap.ScaleControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT}));
map.addControl(new window.BMap.NavigationControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT }));
}
(3)绘制路线
// 绘制用户的行驶路线
drawBikeRoute = (positionList)=>{
let map = this.map;
let startPoint = '';
let endPoint = '';
// lon 经度 lat 纬度
if (positionList.length>0){ // 判断行驶轨迹是否存在
let first = positionList[0];
let last = positionList[positionList.length-1];
startPoint = new window.BMap.Point(first.lon,first.lat);// 获取地图点
// 创建开始坐标点的图标
let startIcon = new window.BMap.Icon('/assets/start_point.png',
new window.BMap.Size(36,42),{// 整个图标
imageSize:new window.BMap.Size(36,42), // 图片的大小
anchor: new window.BMap.Size(18, 42)
})
// marker是为了将icon图标嵌入到地图里面,并且要设置坐标点实现点
let startMarker = new window.BMap.Marker(startPoint, { icon: startIcon});
this.map.addOverlay(startMarker);
// 创建结束坐标点的图标
endPoint = new window.BMap.Point(last.lon, last.lat);
let endIcon = new window.BMap.Icon('/assets/end_point.png', new window.BMap.Size(36, 42), {
imageSize: new window.BMap.Size(36, 42),
anchor: new window.BMap.Size(18, 42)
})
// marker是为了将icon图标嵌入到地图里面,并且要设置坐标点实现点
let endMarker = new window.BMap.Marker(endPoint, { icon: endIcon });
this.map.addOverlay(endMarker);
// 连接路线图
let trackPoint = [];
for(let i=0;i<positionList.length;i++){
let point = positionList[i];
trackPoint.push(new window.BMap.Point(point.lon, point.lat));
}
// 设置线的样式
let polyline = new window.BMap.Polyline(trackPoint,{
strokeColor:'#1869AD',
strokeWeight:3,
strokeOpacity:1
})
this.map.addOverlay(polyline);
this.map.centerAndZoom(endPoint, 11);
}
}
(4) 绘制服务区地图
// 绘制服务区
drwaServiceArea = (positionList)=>{
// 连接路线图
let trackPoint = [];
for (let i = 0; i < positionList.length; i++) {
let point = positionList[i];
trackPoint.push(new window.BMap.Point(point.lon, point.lat));
}
// 绘制服务区
let polygon = new window.BMap.Polygon(trackPoint, {
strokeColor: '#CE0000',
strokeWeight: 4,
strokeOpacity: 1,
fillColor: '#ff8605',
fillOpacity:0.4
})
this.map.addOverlay(polygon);
}
- echart的使用
安装
sudo yarn add echarts-for-react --save
sudo yarn add echarts --save
引用
import ReactEcharts from 'echarts-for-react';
import echarts from 'echarts/lib/echarts'
可以按需引用echart中某一个组件
// 引入饼图和折线图
import 'echarts/lib/chart/pie'
使用
getOption() {
let option = {
title: {
text: '用户骑行订单',
x : 'center'
},
legend : {
orient: 'vertical',
right: 10,
top: 20,
bottom: 20,
data: ['周一','周二','周三','周四','周五','周六','周日']
},
tooltip: {
trigger : 'item',
formatter : "{a} <br/>{b} : {c} ({d}%)"
},
series: [
{
name : '订单量',
type : 'pie',
radius : '55%',
center : [
'50%', '60%'
],
data:[
{
value:1000,
name:'周一'
}
],
itemStyle : {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
}
return option;
}
```bash
// render中渲染
<ReactEcharts
option={this.getOption()}
style={{ height: 500 }}/>
11. 富文本编辑器的使用 ------ react-draft-wysiwyg
安装富文本组件以及将组件内容装换成html格式的draftjs
```bash
sudo yarn add react-draft-wysiwyg draftjs-to-html --save ```
更多推荐
所有评论(0)