4、谷粒后台商品管理组件
基本路由
<Switch>
<Route path='/product' component={ProductHome} exact />
{/*路径完全匹配*/}
<Route path='/product/addupdate' component={ProductAddUpdate} />
<Route path='/product/detail' component={ProductDetail} />
<Redirect to='/product' />
</Switch>两种分页技术
前台分页
后台直接返回全部数据
后台分页
后台返回给前台当前页数与总页数
前台需要传递当前页码数与每页数量
跳转路由时传递参数
跳转路由
this.props.history.push('/product/detail', { product })接受参数
const { pCategoryId, categoryId } = this.props.location.state.productReact中输出HTML标签
<span dangerouslySetInnerHTML={{ __html: detail }}></span>级联选择器
<Cascader
options={this.state.options}
loadData={this.loadData}
onChange={this.onChange}
changeOnSelect
/>options数据源
loadData加载数据的回调函数
changeOnSelect当此项为 true 时,点选每级菜单选项值都会发生变化,具体见上面的演示
onChange选择完成后的回调
loadData = (selectedOptions) => {
// 的到选择的option对象
const targetOption = selectedOptions[selectedOptions.length - 1]
// loading效果
targetOption.loading = true
// load options lazily
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)
}获取分类
export default class ProductAddUpdate extends Component {
formRef = React.createRef()
state = {
options: []
}
initOptions = (categorys) => {
// 根据categorys数组生成options数组
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) => {
// 的到选择的option对象
const targetOption = selectedOptions[selectedOptions.length - 1]
// loading效果
targetOption.loading = true
// 根据选中的分类请求获取下一级分类
const subCategorys = await this.getCategorys(targetOption.value)
if (subCategorys && subCategorys.length > 0) {
// 生成二级列表options
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()
}
}默认分类
initOptions = async (categorys) => {
// 根据categorys数组生成options数组
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)
// 生成二级下拉列表的options
const childOptions = subCategorys.map((c) => ({
value: c._id,
label: c.name,
isLeaf: true
}))
// 找到当前商品对应的option对象
const targetOption = options.find(
(option) => option.value === pCategoryId
)
// 关联到对应的一级options
targetOption.children = childOptions
}
// 更新状态
this.setState({ options })
}上传图片
上传组件:https://ant.design/components/upload-cn/
上传图片时所触发的回调函数中file与fileList最后一个元素不是同一个。因此修改的并不是file,而是fileList最后一个元素
// file:当前操作的图片文件
// fileList:所有已上传的文件对象
handleChange = ({ file, fileList }) => {
// 一旦上传成功,将当前上传的file的信息修正
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中的表单。例如
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}子组件定义方法返回需要的列表,父组件调用此方法即可。
编辑时显示图片
编辑时显示图片涉及到fileList图片列表的初始值。因此需要接受数据来判断是否存在。如果存在则生成有图片的列表
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
}
}父组件只需要将图片列表传递给子组件即可。
富文本编辑器
安装插件
yarn add react-draft-wysiwyg draftjs-to-html draft-js<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}
/>图片上传
// 图片上传
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)
})
})
} 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小康博客!
评论
TwikooDisqusjs









