Reactjs的项目中,想要实现:
上传照片和查看照片
且点击单张照片可以全屏查看大图。可以不支持缩放查看。
希望先去调研,如果可以的话,尽量用H5页面实现这些功能
刚巧最近看到微信的weui,如果可以用的话,还是很不错的。
-》
weui/weui.js: A lightweight javascript library for WeUI.
且刚去手机端预览:
用Android端的浏览器打开的效果很赞:
示例代码:
weui.js/uploader.md at master · weui/weui.js
然后就是先去:
然后就是去:
尽量用react-weui的uploader去实现移动端的文件上传了。
然后用代码:
// import { Page, Gallery, GalleryDelete, Uploader, Form, Cell, CellBody } from ‘react-weui’; import { Gallery, GalleryDelete, Uploader } from ‘react-weui’; // import photoSrc from ‘../../../assets/photo.png’; // import thumbSrc from ‘../../../assets/thumb.png’; import imgCow1 from ‘../../../assets/cow_1.jpg’; import imgCow2 from ‘../../../assets/cow_2.jpg’; import imgCow3 from ‘../../../assets/cow_3.jpg’; import imgCow4 from ‘../../../assets/cow_4.jpg’; export default class CowEditAdd extends Component { gallery: false, demoFiles : [ { url: imgCow1 }, { url: imgCow2, status: ‘38%’ } // { // url: imgCow4 // } // { // url: thumbSrc // }, // { // url: thumbSrc // }, // { // url: thumbSrc // }, // { // url: photoSrc, // error: true // }, // { // url: thumbSrc, // status: ‘50%’ // } ] }; renderGallery(){ if (!this.state.gallery) return false; let srcs = this.state.demoFiles.map(file=>file.url); // defaultIndex={this.state.gallery.id} return ( <Gallery src={srcs} show defaultIndex={0} onClick={(e)=> { console.log(e); //avoid click background item e.preventDefault(); e.stopPropagation(); this.setState({gallery: false}); }} > <GalleryDelete onClick={(e, id)=> { this.setState({ demoFiles: this.state.demoFiles.filter((e,i)=>i !== id), gallery: this.state.demoFiles.length <= 1 ? true : false }); }} /> </Gallery> ); } render() { return ( 。。。 <ul class={style.uploadImage}> {this.renderGallery()} <Uploader title="牛只照片(左-中-右)" maxCount={3} maxWidth={720} files={this.state.demoFiles} onError={msg => alert(msg)} onChange={(file, e) => { console.log("Uploader onChange", file, e); let newFiles = […this.state.demoFiles, {url:file.data}]; this.setState({ demoFiles: newFiles }); }} onFileClick={ (e, file, i) => { console.log(‘file click’, file, i); this.setState({ gallery: { url: file.url, id: i } }); } } lang={{ maxError: maxCount => `最多只允许上传${maxCount}张图片` }} /> </ul> </div> ); } } // <Page className="cell" title="Uploader" subTitle="上传组件,一般配合Gallery使用"> // { this.renderGallery() } // <Form> // <Cell> // <CellBody> // </CellBody> // </Cell> // </Form> // </Page> |
css:style.less
// .cows_n_box ul.uploadImage { // position: relative; // height: 1.8rem; // border-bottom: none; // // > ul{ // // border-bottom: none; // // } // } .uploadImage { position: relative; height: 2.46rem !important; border: none !important; } // .uploadImage { // position: relative; // height: 1.8rem; // border: none; // } // .cows_n_box ul { // .uploadImage { // position: relative; // height: 1.8rem; // border: none; // } // } //for weui-uploader__files // ul.weui-uploader__files{ // .weui-uploader__files{ .cows_n_box ul div div ul { position: relative; height: 0.001rem !important; border-bottom: none !important; } //weui-uploader__file .cows_n_box ul div div ul li { // padding: 0.1rem 0.66rem 0.1rem 1.3rem; padding: 0 !important; } |
然后实际测试出来的效果是:
1.gallery问题很多
(1)gallery有bug,或者是使用上有问题,不能滑动到下一张图片
第一张之后的图片是黑色背景,无法显示
(2)且gallery中删除图标也看不到。
(3)图片自动压缩也不起效果-》设置了maxWidth无效,导入的图片还是原图
2.没法选择上传照片 + 在部分手机上无法调用拍照功能
Android手机上,官网的demo中,点击+,是可以弹出:
选择照片和拍照的
但是真机上:
部分android手机(锥子M1L,iPhone6),直接进入拍照功能
部分android手机(VIVO Y51A,Huawei TIT-CL00),都无法使用拍照功能
【总结】
所以,总体上来说,和官网的demo,差异还是很大,问题还是不少的。
所以,放弃了直接使用weui中的uploader去上传文件。还是自己去手动实现吧。
【后记1】
然后也去找相关的库:
react.js uploader
lionng429/react-file-uploader: A set of file-upload-components with React.js.
是拖放上传的。不符合此处期望,放弃
aleksei0807/react-images-uploader: React.js component for uploading images to the server
好像还有可能用用试试。
不清楚,看起来不够好。
react js image uploader
Image Upload and Manipulation with React | CSS-Tricks
也是拖放上传。
reactjs – How to upload an image in React JS? – Stack Overflow
Image upload with ReactJS – Stack Overflow
react js image upload
Upload Image File Component Fun
Image uploading with React.js, Node.js, and AWS S3
jquery – Upload File Component with ReactJS – Stack Overflow
【后记2】
【记录】尝试去用H5实现弹出选择相机还是相册的方式实现图片文件上传
【总结】
所以还是只能放弃H5页面的上传照片的方式了。
只能想办法,让iOS和android开发人员去实现选择和上传照片的功能,然后自己只是负责H5页面缩略图显示和点击后图片查看的功能了。
最后是别人写好了html+css,然后自己整合进来,再调用原生app的接口去实现图片上传的
reactjs部分的代码如下:
const COW_IMG_TYPE = { LEFT: "left", MIDDLE: "middle", RIGHT: "right" }; export default class CowEditAdd extends Component { state = { cowImgLeft: { "isAdded" : false, "thumbnailUrl" : "", "originUrl" : "" }, cowImgMiddle: { "isAdded" : false, "thumbnailUrl" : "", "originUrl" : "" }, cowImgRight: { "isAdded" : false, "thumbnailUrl" : "", "originUrl" : "" } getCowImgObjFromType(cowImgType){ let cowImgObj = null; if (cowImgType === COW_IMG_TYPE.LEFT){ cowImgObj = this.state.cowImgLeft; } else if (cowImgType === COW_IMG_TYPE.MIDDLE){ cowImgObj = this.state.cowImgMiddle; } else if (cowImgType === COW_IMG_TYPE.RIGHT){ cowImgObj = this.state.cowImgRight; } console.log(`getCowImgObjFromType: ${cowImgType} -> ${JSON.stringify(cowImgObj)}`); return cowImgObj; } onCowImgBoxClick(cowImgType){ console.log(`onCowImgBoxClick: cowImgType=${cowImgType}`); toast(`点击了${cowImgType}牛只照片`); let cowImgObj = this.getCowImgObjFromType(cowImgType); if (cowImgObj) { if (cowImgObj.isAdded) { this.showCowImage(cowImgType); } else { let cowCode = ""; if (this.props.type === COW_ACTION_TYPE.EDIT) { cowCode = this.state.cowCode; } else if (this.props.type === COW_ACTION_TYPE.ADD) { cowCode = ""; } this.uploadCowImg(cowCode, cowImgType); } } } showCowImage(cowImgType){ console.log(`showCowImage: cowImgType=${cowImgType}`); // toast(`显示牛只${cowImgType}照片`); let cowImgObj = this.getCowImgObjFromType(cowImgType); if (cowImgObj) { let gallery = weui.gallery(cowImgObj.originUrl, { className: ‘cowImageGallary’, onDelete: () => { gallery.hide(() => {}); this.deleteCowImage(cowImgType); } }); } } uploadCowImg(cowCode, cowImgType){ console.log(`uploadCowImg: cowCode=${cowCode}, cowImgType=${cowImgType}`); toast(`上传牛只 ${cowCode} ${cowImgType}照片`, 2000); // console.log(window); console.log(window.AppHost); if (window.AppHost !== undefined) { console.log(window.AppHost.uploadCowImage); //Native(iOS/Android) uploadCowImage(cowCode, cowImageType) window.AppHost.uploadCowImage(cowCode, cowImgType); } else { // toast(‘找不到支持上传牛只图片的功能’); //for debug let debugImgUrl = ""; // debugImgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502094214839&di=e08c056c667c3c27e672a4f240da1675&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimage%2Fc0%253Dshijue1%252C0%252C0%252C294%252C40%2Fsign%3D79c5c60e8c18367ab984779e461ae1a1%2Fdbb44aed2e738bd47a88b916ab8b87d6277ff968.jpg"; debugImgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502084214262&di=3ff4eca5cc6d4c384a83e09877006772&imgtype=0&src=http%3A%2F%2Fimgsrc.baidu.com%2Fimgad%2Fpic%2Fitem%2F023b5bb5c9ea15ce94e6792cbc003af33a87b28f.jpg"; // debugImgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502096249512&di=7549c67f02f48ac9f0730bf7437cd356&imgtype=0&src=http%3A%2F%2Fcdn.duitang.com%2Fuploads%2Fitem%2F201411%2F06%2F20141106222213_WBZa8.thumb.700_0.jpeg"; // debugImgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b10000_10000&sec=1502074137&di=79361fb1a9244c3d6d98f96fb728ce12&src=http://www.1866.tv/Upload_Map/2015nian/10/20/2015-10-20-14-02-46352.jpg"; // debugImgUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1502096360787&di=b1c39bb12683e9f6235d1be496dc04aa&imgtype=0&src=http%3A%2F%2Fpic.qjimage.com%2Fchineseview077%2Fhigh%2F75-19421.jpg"; let uploadResultJsonStr = ` { "isUploaded" : true, "cowInfo" : { "cowImageType" : "left", "originUrl" : "${debugImgUrl}", "thumbnailUrl" : "${debugImgUrl}" } } `; this.uploadCowImageCallback(uploadResultJsonStr); } } //Native(iOS/Android)uploadCowImageCallback(String uploadResultJsonStr); uploadCowImageCallback(uploadResultJsonStr){ console.log(`uploadCowImageCallback: uploadResultJsonStr=${uploadResultJsonStr}`); weui.alert(uploadResultJsonStr); let uploadResultDict = JSON.parse(uploadResultJsonStr); console.log(uploadResultDict); if (uploadResultDict.isUploaded){ let cowImgType = uploadResultDict.cowInfo.cowImageType; toast(`cowType=${uploadResultDict.cowInfo.cowImageType}`); if (cowImgType === COW_IMG_TYPE.LEFT){ this.setState({ cowImgLeft : { "isAdded" : true, "originUrl" : uploadResultDict.cowInfo.originUrl, "thumbnailUrl" : uploadResultDict.cowInfo.thumbnailUrl } }); } else if (cowImgType === COW_IMG_TYPE.MIDDLE){ this.setState({ cowImgMiddle : { "isAdded" : true, "originUrl" : uploadResultDict.cowInfo.originUrl, "thumbnailUrl" : uploadResultDict.cowInfo.thumbnailUrl } }); } else if (cowImgType === COW_IMG_TYPE.RIGHT){ this.setState({ cowImgRight : { "isAdded" : true, "originUrl" : uploadResultDict.cowInfo.originUrl, "thumbnailUrl" : uploadResultDict.cowInfo.thumbnailUrl } }); } } else { toast("上传图片失败!"); } } onCowImgLeftBoxClick(){ this.onCowImgBoxClick(COW_IMG_TYPE.LEFT); } onCowImgMiddleBoxClick(){ this.onCowImgBoxClick(COW_IMG_TYPE.MIDDLE); } onCowImgRightBoxClick(){ this.onCowImgBoxClick(COW_IMG_TYPE.RIGHT); } doDeleteCowImg(cowImgType){ console.log(`doDeleteCowImg: cowImgType=${cowImgType}`); //TODO: call api to delete cow image toast(`删除牛只${cowImgType}照片`); //for debug if (cowImgType === COW_IMG_TYPE.LEFT){ this.setState({ cowImgLeft : { "isAdded" : false, "originUrl" : "", "thumbnailUrl" : "" } }); } else if (cowImgType === COW_IMG_TYPE.MIDDLE){ this.setState({ cowImgMiddle : { "isAdded" : false, "originUrl" : "", "thumbnailUrl" : "" } }); } else if (cowImgType === COW_IMG_TYPE.RIGHT){ this.setState({ cowImgRight : { "isAdded" : false, "originUrl" : "", "thumbnailUrl" : "" } }); } } deleteCowImage(cowImgType){ console.log(`deleteCowImage: cowImgType=${cowImgType}`); let cowImgTypeStr = ""; if (cowImgType === COW_IMG_TYPE.LEFT){ cowImgTypeStr = "左"; } else if (cowImgType === COW_IMG_TYPE.MIDDLE){ cowImgTypeStr = "中"; } else if (cowImgType === COW_IMG_TYPE.RIGHT){ cowImgTypeStr = "右"; } let deleteImgDialog = weui.dialog({ title: ‘确认要删除牛只’ + cowImgTypeStr + ‘照片?’, content: ”, // className: ‘custom-classname’, buttons: [{ label: ‘取消’, type: ‘default’, onClick: () => { console.log("取消删除", deleteImgDialog); deleteImgDialog.hide(() => {}); } }, { label: ‘确定’, type: ‘primary’, onClick: () => { console.log("确定删除", deleteImgDialog); deleteImgDialog.hide(() => {}); this.doDeleteCowImg(cowImgType); } }] }); } onDeleteClick(cowImgType, e){ console.log(`onDeleteClick: cowImgType=${cowImgType}`); // e.preventDefault(); e.stopPropagation(); e.nativeEvent.stopImmediatePropagation(); this.deleteCowImage(cowImgType); } onLeftDeleteClick(e){ this.onDeleteClick(COW_IMG_TYPE.LEFT, e); } onMiddleDeleteClick(e){ this.onDeleteClick(COW_IMG_TYPE.MIDDLE, e); } onRightDeleteClick(e){ this.onDeleteClick(COW_IMG_TYPE.RIGHT, e); } render() { return ( <div class={style.content_div}> <div class={style.cows_n_box}> <dl> <dt>牛只照片(左-中-右)</dt> <dd class={style.clearfix}> <div class={this.state.cowImgLeft.isAdded ? style.nz_tp_box_noImgBkg : style.nz_tp_box_addImgBkg} onClick={this.onCowImgLeftBoxClick} > {this.state.cowImgLeft.isAdded ? (<img src={this.state.cowImgLeft.thumbnailUrl} />) : (null)} {this.state.cowImgLeft.isAdded ? (<i onClick={this.onLeftDeleteClick} />) : (null)} </div> <div class={this.state.cowImgMiddle.isAdded ? style.nz_tp_box_noImgBkg : style.nz_tp_box_addImgBkg} onClick={this.onCowImgMiddleBoxClick} > {this.state.cowImgMiddle.isAdded ? (<img src={this.state.cowImgMiddle.thumbnailUrl} />) : (null)} {this.state.cowImgMiddle.isAdded ? (<i onClick={this.onMiddleDeleteClick} />) : (null)} </div> <div class={this.state.cowImgRight.isAdded ? style.nz_tp_box_noImgBkg : style.nz_tp_box_addImgBkg} onClick={this.onCowImgRightBoxClick} > {this.state.cowImgRight.isAdded ? (<img src={this.state.cowImgRight.thumbnailUrl} />) : (null)} {this.state.cowImgRight.isAdded ? (<i onClick={this.onRightDeleteClick} />) : (null)} </div> </dd> </dl> css部分: .cows_n_box dl { height: 2.53rem; position: relative; padding: 0.16rem 0.3rem; border-bottom: 1px solid #cccac9; } .cows_n_box dl dt { line-height: 0.6rem; font-size: 0.3rem; color: #272727; font-weight: normal; } .cows_n_box dl dd { padding: 0.2rem 0 0.15rem; clear: both; } .nz_tp_box_common { width: 1.24rem; height: 1.24rem; position: relative; display: inline-block; float: left; margin-right: 0.5rem; background-size: 1.24rem 1.24rem; box-sizing: border-box; } .addImgBkg{ background: url("@{env-prefix}/assets/nz_add_bg.png") center center no-repeat; } .noImgBkg{ background: url("@{env-prefix}/assets/nz_tp_bg.png") center center no-repeat; } .nz_tp_box_addImgBkg{ .addImgBkg; .nz_tp_box_common; } .nz_tp_box_noImgBkg{ .noImgBkg; .nz_tp_box_common; } // .nz_tp_box img { .nz_tp_box_noImgBkg img{ max-height: 100%; max-width: 100%; width: auto; height: auto; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } // .nz_tp_box i { .nz_tp_box_noImgBkg i { position: absolute; display: inline-block; width: 0.5rem; height: 0.5rem; top: -0.25rem; right:-0.25rem; // background: url(../images/nz_close.png) no-repeat; background: url("@{env-prefix}/assets/nz_close.png") no-repeat; background-size: 0.5rem 0.5rem; } |
效果:
后面的事情,就是和原生app去联合调试,完善代码,去调用后台API接口去delete图片了。
转载请注明:在路上 » 【已解决】ReactJS中如何上传照片和查看照片