第一次接触前端。不管是之前用过asp.net写网页还是啥的。
要求用antd插件,认知是阿里公开的控件,供大家使用。有示例代码。但是最麻烦的是官方示例是Js的,我没学过。。。。当然ts我也没学过。但是有同事代码,我扣扣索索,再看看视频,还是可以动手的。话说回来,B站那个IT营的ts教程视频的那位老师,口音太重了,我看到18节实在听不下去了,山西口音太重了点,。后期应该还是要找个视频好好了解下的。
我不知道是我搜索问题还是什么原因,TS搞这个andt的upload,感觉没找到,可能JS很容易就转化过去导致的。
我直接放图:(不会用gif,直接三连)很简单的单张图片上传。
下面是经过删减的TS代码,其中store的代码就不放了,没什么难度和价值的。
import GoodsPageStore from '@home/router/system/GoodsPage/store'
import React, { Component } from 'react'
import { inject, observer } from 'mobx-react'
import { Button, Form, Input, Upload, message } from 'antd'
import Modal from 'antd/lib/modal/Modal'
import { GoodsModel } from '@home/model/GoodsModel'
import { LoadingOutlined, PlusOutlined } from '@ant-design/icons'
import config from '@/config/config'
interface Props {
goodsPageStore?: GoodsPageStore
formRef: React.RefObject<any>
}
// @ts-ignore
@inject('goodsPageStore') @observer
export class Edit extends Component<Props> {
// 原先一直以为imageUrl应该在这里给一个类型,没想到可以直接赋值
state = {
loading: false,
imageUrl: '',
}
// item的格式
// @ts-ignore
formItemLayout = {
oneCol: {
labelCol: { span: 3 },
wrapperCol: { span: 21 },
},
twoCol:{
labelCol: {span: 4},
wrapperCol: {span: 16},
},
threeCol: {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
},
}
render () {
const { goodsPageStore, formRef } = this.props
let { loading, imageUrl } = this.state
// 这个按钮看起来是判断这个按钮的状态的,是+型还是转动型的
const uploadButton = (
<div>
{loading ? <LoadingOutlined/> : <PlusOutlined/>}
<div style={{ marginTop: 8 }}>Upload</div>
</div>
)
return (
<Modal
forceRender
maskClosable={false}
width={700} title="商品编辑" visible={goodsPageStore?.editing} onCancel={this.onClose}
footer={
<div>
<Button type="primary" onClick={this.onClose}>取消</Button>
<Button type="primary" loading={goodsPageStore?.saving}
onClick={() => formRef.current.submit()}>确定</Button>
</div>
}>
<Form ref={formRef} onFinish={this.onFinish}>
<Form.Item colon={goodsPageStore?.hidden} label="图片" name="goodsImage"
{...this.formItemLayout.twoCol}>
<Upload
name="goodsImage"
// 图像框显示类型
listType="picture-card"
className="avatar-uploader"
showUploadList={false}
// 图片上传接口地址
action={`${config.protocol + config.host}/basic/file/upload`}
// 上传请求方式
method={'POST'}
beforeUpload={this.beforeUpload}
// 最重要的就是这个data, 传递 参数的,我这里接口只有一个file作为参数,这里就只有一个
data={file => ({ file: file })}
// 因为handleChange 这个事件触发的改动,修改状态
onChange={this.handleChange}
>
<div>
{goodsPageStore?.goods.goodsImage ?
<img src={goodsPageStore?.goods.goodsImage} alt="goodsImage"
style={{ width: '100%' }}
/>
: uploadButton}
</div>
</Upload>
</Form.Item>
</Form>
</Modal>
)
}
handleChange = async(info: any) => {
if (info.file.status === 'uploading') {
this.setState({ loading: true })
console.log('uploading')
return
}
if (info.file.status === 'done') {
// 取url
console.log('done')
this.getBase64(info.file.originFileObj, (imageUrl: any) =>
this.setState({
imageUrl: info.file.response.url,
loading: false,
}),
)
// 此处是给保存时保存地址用的。
const { goodsPageStore } = this.props
await goodsPageStore?.setImage(info.file.response.url)
}
}
getBase64 = (img: any, callback: any) => {
// 创建FileReader接口(把文件放到图片预览框里面)
const reader = new FileReader()
// 类似 reader.onloadend = function () { preview.src = reader.result; }
reader.addEventListener('load', () => callback(reader.result))
reader.readAsDataURL(img)
}
/**
* 限定上传格式和大小。
* */
beforeUpload = (file: any) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isJpgOrPng) {
message.error('系统仅支持上传JPEG/JPG/PNG格式的图片!')
}
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
message.error('上传图片大小必须小于2MB!')
}
console.log('限定格式大小的判断完成了')
return isJpgOrPng && isLt2M
}
}