基于antd的react开发,后台管理系统

一. js 控制跳转页面:

可用 <Link to={{ pathname: `url`, state: someData }} > | | this.props.match.history.push('url', state) | | <Redirect to={url}>路由组件

import React, { Component } from 'react'
import { Link, Redirect } from 'react-router-dom'
Class myTest extends Components {
constrouter(props){
  super(props)
    this.state = {
      redirect:false,
    }
  }
changePage() {
this.setState({ redirect : true })
}
render() {
  return(
  <div>
    { redirect ? <Redirect push to= {url}> : ' ' } //重定向
    <button onClick={ this.changePage.bind(this) }>点击改变<button>
<Link to={{ pathname: `url`, state: someData }}><Button>直接跳转</Button></Link>   </div>   ) } }

二. this.props.match.history

获取history:页面级this.props.match.history存在,可把history传给组件级(this.props.match.history.push == window.location.href)

注:可以通过调用对象的方法从url堆栈中push或者pop url出来。window.history.pushState(null,null,url)就是向当前文档的url堆栈中push一个新的url。使用window.history.pushState(null,null,url)是不会使用参数url和当前的url拼接产生新的url跳转的(但页面级跳转还是带参数到url比较妥,以防无痕浏览,url长度不超过1000且不是用来在多窗口里通讯的,而是为单页面 url 状态管理服务的)。

三. 吐槽,蚂蚁金服的antd好多bug啊!!

1.Select组件下拉列表生成的位置竟然在html最下方,会跟着页面滚动!!需要<Select>加上getPopupContainer={trigger => trigger.parentNode}属性

2.Table组件fix列后hover会不停的重新渲染clumns的render内容,对最底层组件的componentWillReceiveProps(父props更新改变自身的state)不断被刷新可能导致部分功能失效,由于蚂蚁金服没有暴露这个hover事件,暂无解决办法。3.<form>组件内给<select>附初值initialValue可以附option的value索引

<Option key={ control ? item.id : item.paramValue} value={ control ? item.id : item.paramValue}></Option>

key和value都要加上(antd官方文档说只加key就可以呵呵)

坑爹的antd<table>组件!!rowSelection单条点击onChange函数返回的第二个参数selectedRows有时会丢失,设置单条点击回点某个点过的选项顺序不变!!,只能通过selectedRowKeys去遍历dataSource获得某条所有信息!!!

4.<form>标签,用form.setFieldsValue方法要先赋初始值

const { getFieldDecorator, setFieldsValue } = this.props.form

for (let key in data) {

getFieldDecorator(key, { initialValue: undefined })

} // 用form.setFieldsValue方法要先赋初始值

setFieldsValue(data)

getFieldDecorator方法的要想组件获取到initialValue的值,必须在最外层,不能<div></div>在包裹:

<FormItem label='测试' colon={false}> // colon设置false标签后的冒号消失
   {getFieldDecorator('test', {
      initialValue: this.state.test
    })(
      <Input />  // 要想Input组件获得initialValue值,必须在最外层
    )}
</FormItem>

validateFields校验函数第一个参数可传需要校验的数组(选填):

this.props.form.validateFields(['title'], (err, values) => {
      if (err) return
  })  // 只校验'title'

5.<TreeSelect>:

树形下拉框默认值type为string。

allowClear(清除所有按钮)在onChange函数里的第三个参数extra的allCheckedNodes属性会丢失。

6.<Table> 有个loading属性,向后台请求数据时候loading=true,加载好数据后loading=false。

7.<Table>列表只可选择单项:

class membership extends Component {
  constructor(props) {
    super(props)
    this.state = {
        selectedRowKeys: [], // 被选中列表的id
        selectDetails: {}, // 被选中列表的详细内容
dataSource: [], // 列表数据 pagination: { pageSize: 10, current: 1, total: 0, showSizeChanger: true, pageSizeOptions: ['10', '20', '50', '100'], }, } } // 表格列表点击
onSelectChange(selectedRowKeys, selectDetails) { // antd此函数第二个参数有问题
const { dataSource } = this.state
const selectedRowKeysChange = selectedRowKeys.splice(selectedRowKeys.length - 1)
const selectDetailsChange = dataSource.filter((item) => (item['id'] === selectedRowKeysChange[0])) // 可遍历数据列表获得想要数据条
this.setState({ selectedRowKeys: selectedRowKeys.splice(selectedRowKeys.length - 1), selectDetails: selectDetailsChange
})

}

render() {
      const rowSelection = {
        selectedRowKeys,
        onChange: this.onSelectChange,
    }
    return <div>
       <Table
      className={style['table-one']}
      dataSource={this.state.dataSource}
      locale={{ emptyText: '暂无数据' }}
      rowKey={record => record.id}
      rowSelection={rowSelection}
      pagination={this.state.pagination}
      bordered columns={columns} loading={loading} />
    </div>
    }
}

css把table所有可勾选按钮隐藏:

.table {
  margin: 10px 0;
  :global(.ant-table-thead .ant-table-selection-column .ant-checkbox-wrapper) {
    display: none;
  }
}

8. antd的DatePicker汉化,项目入口文件(index.js)里设置:

// 时间选择汉化
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
时间戳转化成年月日时分秒:moment(val.gmtCreated).format('YYYY-MM-DD HH:mm:ss')
年月日时分秒转化成时间戳: time.valueOf()

四. 获取挂载好dom上的html代码

可在componentDidMout生命周期获得:

constructor(props) {
    super(props)
    this.test = React.createRef()
}
componentDidMout(){
console.log(this.test)
// 或者:ReactDOM.findDOMNode(this || this.refs.Test) // 传入this是当前组件的dom } render() { return ( <div ref={this.test || 'Test'}> </div> ) // 两种方式 }

五. render渲染中过滤非jsx元素数据:

render {
 const { list = []} = this.state
  return ({
    list.map((item, index)=> {
      if (item.selected) {
          return <div key={ index }>{item}</div>
      }
    }).filter(React.isValidElement)
  })
}

六. 关于前端测试环境模拟后台接口数据mock.js在index.js的引入:

if (process.env.NODE_ENV === 'development') {
  require('Contants/mock') // mock.js所在目录
}

mock.js:

Mock.mock(`${baseUrl}/industry/material/listMaterial`, (options) => {
  const requestData = JSON.parse(options.body) //解析传参
  const data = [] // 模拟返回值
  return data
})

注:mock拦截地址一定要完整

七.create-react-app脚手架本地开发中跨域问题:

1.加入proxy配置

start.js文件里使用WebpackDevServer本地启动了一个服务器,封装了配置可做代理

直接在package.json里填写即可:

"proxy": "目标url"

或者代理多项:

"proxy": {
    "/gateway": {   // baseUrl = '/gateway'
      "target": "目标路径",
      "changeOrigin": true,
      "pathRewrite": {
        "^/gateway": "/"    // 路径匹配替换'/gateway' ===> '/'
      }
    },
    "/api": {
      "target": "目标路径",
      "changeOrigin": true,
      "pathRewrite": {
        "^/api": "/"         // 路径匹配替换'/api' ===> '/'
      }
    }
}