基本路由
1 2 3 4 5 6 7
| <Switch> <Route path='/product' component={ProductHome} exact /> {} <Route path='/product/addupdate' component={ProductAddUpdate} /> <Route path='/product/detail' component={ProductDetail} /> <Redirect to='/product' /> </Switch>
|
两种分页技术
前台分页
后台直接返回全部数据
后台分页
后台返回给前台当前页数与总页数
前台需要传递当前页码数与每页数量
跳转路由时传递参数
跳转路由
1
| this.props.history.push('/product/detail', { product })
|
接受参数
1
| const { pCategoryId, categoryId } = this.props.location.state.product
|
React中输出HTML标签
1
| <span dangerouslySetInnerHTML={{ __html: detail }}></span>
|
级联选择器
1 2 3 4 5 6
| <Cascader options={this.state.options} loadData={this.loadData} onChange={this.onChange} changeOnSelect />
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| loadData = (selectedOptions) => { const targetOption = selectedOptions[selectedOptions.length - 1] targetOption.loading = true
setTimeout(() => { targetOption.loading = false targetOption.children = [ { label: `${targetOption.label} Dynamic 1`, value: 'dynamic1', isLeaf: true }, { label: `${targetOption.label} Dynamic 2`, value: 'dynamic2', isLeaf: true } ] this.setState({ options: [...this.state.options] }) }, 1000) }
|
获取分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| export default class ProductAddUpdate extends Component { formRef = React.createRef() state = { options: [] } initOptions = (categorys) => { const options = categorys.map((c) => ({ value: c._id, label: c.name, isLeaf: false })) this.setState({ options }) }
getCategorys = async (parentId) => { parentId = parentId || '0' const result = await reqCategorys(parentId) if (result.status !== 0) return message.error('分类获取失败') const categorys = result.data if (parentId === '0') { this.initOptions(categorys) } else { return categorys } } loadData = async (selectedOptions) => { const targetOption = selectedOptions[selectedOptions.length - 1] targetOption.loading = true
const subCategorys = await this.getCategorys(targetOption.value) if (subCategorys && subCategorys.length > 0) { const cOptions = subCategorys.map((c) => ({ value: c._id, label: c.name, isLeaf: true })) targetOption.children = cOptions } else { targetOption.isLeaf = true } targetOption.loading = false this.setState({ options: [...this.state.options] }) } componentDidMount() { this.getCategorys() } }
|
默认分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| initOptions = async (categorys) => { const options = categorys.map((c) => ({ value: c._id, label: c.name, isLeaf: false })) const { isUpdate, product } = this const { pCategoryId, categoryId } = product if (isUpdate && pCategoryId !== '0') { const subCategorys = await this.getCategorys(pCategoryId) const childOptions = subCategorys.map((c) => ({ value: c._id, label: c.name, isLeaf: true })) const targetOption = options.find( (option) => option.value === pCategoryId ) targetOption.children = childOptions }
this.setState({ options }) }
|
上传图片
上传组件:https://ant.design/components/upload-cn/
上传图片时所触发的回调函数中file
与fileList
最后一个元素不是同一个。因此修改的并不是file,而是fileList
最后一个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
handleChange = ({ file, fileList }) => { if (file.status === 'done') { const result = file.response if (result.status === 0) { message.success('成功了!') const { name, url } = result.data file = fileList[fileList.length - 1] file.name = name file.url = url } else { message.error('失败了!') } } this.setState({ fileList }) }
|
父组件收集子组件的数据
为子组件添加ref
引用。类似于antd4
中的表单。例如
1 2 3 4 5 6 7 8 9
| class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render() { return <div ref={this.myRef} />; } }
|
子组件定义方法返回需要的列表,父组件调用此方法即可。
编辑时显示图片
编辑时显示图片涉及到fileList
图片列表的初始值。因此需要接受数据来判断是否存在。如果存在则生成有图片的列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| constructor(props) { super(props) const { imgs } = this.props let fileList = [] if (imgs && imgs.length > 0) { fileList = imgs.map((img, index) => ({ uid: -index, name: img, status: 'done', url: BASE_IMG_URL + img })) } this.state = { previewVisible: false, previewImage: '', previewTitle: '', fileList } }
|
父组件只需要将图片列表传递给子组件即可。
富文本编辑器
安装插件
1
| yarn add react-draft-wysiwyg draftjs-to-html draft-js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <Editor editorState={editorState} editorStyle={{ border: '1px solid black', minHeight: 200, maxHeight: 500, paddingLeft: 10 }} toolbar={{ image: { uploadCallback: this.uploadImageCallBack, alt: { present: true, mandatory: true } } }} onEditorStateChange={this.onEditorStateChange} />
|
图片上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| uploadImageCallBack = (file) => { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('POST', '/manage/img/upload') const data = new FormData() data.append('image', file) xhr.send(data) xhr.addEventListener('load', () => { const response = JSON.parse(xhr.responseText) const url = response.data.url resolve({ data: { link: url } }) }) xhr.addEventListener('error', () => { const error = JSON.parse(xhr.responseText) reject(error) }) }) }
|