这篇文章主要讲解了“react如何实现图片选择”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“react如何实现图片选择”吧!
react实现图片选择的方法:1、使用import引入“react-native-image-picker”插件;2、使用“
{this.setState({uploadImgs: urls})}}src={uploadImgs}/>”调用实现图片选择上传即可。
React Native七牛上传+本地图片选择
参考:
react-native-image-crop-picker图片选择并裁减 //这个看需求使用https://github.com/ivpusic/react-native-image-crop-pickerreact-native-image-picker图片选择https://github.com/react-native-image-picker/react-native-image-pickerreact-native-qiniuhttps://github.com/buhe/react-native-qiniu
我只要一个多图片上传功能,所以就写简单一点
效果
已上传状态
上传中状态
步骤
手机图片、视频选择功能
用react-native-image-picker插件
yarn add react-native-image-picker;ios需要pod install;
import {launchCamera, launchImageLibrary, ImageLibraryOptions, PhotoQuality} from 'react-native-image-picker';export async function chooseImage(options: { count?: number, quality?: PhotoQuality sourceType?: 'camera', //默认'album'} = {}) { return new Promise<any>(async(resolve, reject) => { const Opts: ImageLibraryOptions = { mediaType: 'photo', quality: options.quality || 1, selectionLimit: options.count || 1 }; const result = options.sourceType == 'camera'? await launchCamera(Opts) : await launchImageLibrary(Opts); resolve(result) })}export async function chooseVideo(options: { count?: number, quality?: 'low' | 'high' sourceType?: 'camera', //默认'album'} = {}) { return new Promise<any>(async(resolve, reject) => { const Opts: ImageLibraryOptions = { mediaType: 'video', videoQuality: options.quality, selectionLimit: options.count || 1 }; const result = options.sourceType == 'camera'? await launchCamera(Opts) : await launchImageLibrary(Opts); resolve(result) })}
七牛上传文件功能
class qiniuUpload { private UP_HOST = 'http://upload.qiniu.com'; // private RS_HOST = 'http://rs.qbox.me'; // private RSF_HOST = 'http://rsf.qbox.me'; // private API_HOST = 'http://api.qiniu.com'; public upload = async(uri:string, key:string, token:string) => { return new Promise<any>((resolve, reject) => { let formData = new FormData(); formData.append('file', {uri: uri, type: 'application/octet-stream', name: key}); formData.append('key', key); formData.append('token', token); let options:any = { body: formData, method: 'post', }; fetch(this.UP_HOST, options).then((response) => { resolve(response) }).catch(error => { console.error(error) resolve(null) }); }) } //...后面再加别的功能}const qiniu = new qiniuUpload();export default qiniu;import qiniu from '@/modules/qiniu/index'... uploadFile: async (filePath: string) => { const res = await createBaseClient('GET', '/v1/file')(); //这是接口请求方法,用来拿后端的七牛token、key if( !res ) { return res; } const { key, token } = res; const fileSegments = filePath.split('.'); const fileKey = key + '.' + fileSegments[fileSegments.length - 1]; try { const result = await qiniu.upload(filePath, fileKey, token) if(result && result.ok) { return { url: ASSET_HOST + '/' + fileKey, //ASSET_HOST是资源服务器域名前缀 }; }else { return null } } catch (error) { return null; } },...
多图上传组件封装
(这里Base、Image、ActionSheet都是封装过的,需看情况调整)
import React from 'react'import { ViewStyle, StyleProp, ImageURISource, ActivityIndicator} from 'react-native'import Base from '@/components/Base';import { Image, View, Text } from '@/components'; //Image封装过的,所以有些属性不一样import ActionSheet from "@/components/Feedback/ActionSheet"; //自己封装import styles from './styleCss'; //样式就不放上来了interface Props { type?: 'video' src?: string[] count?: number btnPath?: ImageURISource style?: StyleProp<ViewStyle> itemStyle?: StyleProp<ViewStyle> itemWidth?: number itemHeight?: number //默认正方形 onChange?: (e) => void}interface State { imageUploading: boolean images: string[]}export default class Uploader extends Base<Props, State> { public state: State = { imageUploading: false, images: [] }; public didMount() { this.initSrc(this.props.src) } public componentWillReceiveProps(nextProps){ if(nextProps.hasOwnProperty('src') && !!nextProps.src){ this.initSrc(nextProps.src) } } private initSrc = (srcProp:any) => { if(!this.isEqual(srcProp, this.state.images)) { this.setState({ images: srcProp }) } } public render() { const { style, btnPath, count, itemStyle, itemWidth, itemHeight, type } = this.props; const { imageUploading, images } = this.state; let countNumber = count? count: 1 return ( <React.Fragment> <View style={[styles.uploaderBox, style]}> {images.length > 0 && images.map((res, ind) => ( <View style={[styles.item, itemStyle]} key={res}> <View style={styles.imgItem}> <Image source={{uri: res}} width={this.itemW} height={this.itemH} onPress={() => { this.singleEditInd = ind; this.handleShowActionSheet() }} /> <Text style={styles.del} onPress={this.handleDelete.bind(null, ind)}>删除</Text> </View> </View> ))} {images.length < countNumber && <View style={[styles.item, itemStyle]}> {imageUploading? ( <View style={[{ width: this.itemW, height: this.itemH, }, styles.loading]}> <ActivityIndicator size={this.itemW*0.4}></Loading> <Text style={{ fontSize: 14, color: '#888', marginTop: 5 }}> 上传中... </Text> </View> ): ( <View style={styles.btn}> <Image source={btnPath || this.assets.uploadIcon} width={this.itemW} height={this.itemH} onPress={() => { this.singleEditInd = undefined; this.handleShowActionSheet() }} /> </View> )} </View> } </View> <ActionSheet name="uploaderActionSheet" options={[{ name: type == 'video'? '拍摄': '拍照', onClick: () => { if(type == 'video') { this.handleChooseVideo('camera') }else if(this.singleEditInd !== undefined) { this.handleChooseSingle('camera') }else { this.handleChooseImage('camera') } } }, { name: '相册', onClick: () => { if(type == 'video') { this.handleChooseVideo() }else if(this.singleEditInd !== undefined) { this.handleChooseSingle() }else { this.handleChooseImage() } } }]} ></ActionSheet> </React.Fragment> ); } private get itemW() { return this.props.itemWidth || 92 } private get itemH() { return this.props.itemHeight || this.itemW; } private isEqual = (firstValue, secondValue) => { if (Array.isArray(firstValue)) { if (!Array.isArray(secondValue)) { return false; } if(firstValue.length != secondValue.length) { return false; } return firstValue.every((item, index) => { return item === secondValue[index]; }); } return firstValue === secondValue; } private handleShowActionSheet = () => { this.feedback.showFeedback('uploaderActionSheet'); //这是显示ActionSheet选择弹窗。。。 } private handleChooseImage = async (sourceType?: 'camera') => { const { imageUploading, images } = this.state; const { count } = this.props if (imageUploading) { return; } let countNumber = count? count: 1 const { assets } = await this.interface.chooseImage({ //上面封装的选择图片方法 count: countNumber, sourceType: sourceType || undefined, }); if(!assets) { return; } this.setState({ imageUploading: true, }); let request:any = [] assets.map(res => { let req = this.apiClient.uploadFile(res.uri) //上面封装的七牛上传方法 request.push(req) }) Promise.all(request).then(res => { let imgs:any = [] res.map((e:any) => { if(e && e.url){ imgs.push(e.url) } }) imgs = [...images, ...imgs]; this.setState({ images: imgs.splice(0,countNumber), imageUploading: false, }, this.handleChange ); }) } private singleEditInd?: number; //修改单个时的索引值 private handleChooseSingle = async(sourceType?: 'camera') => { let { imageUploading, images } = this.state; if (imageUploading) { return; } const { assets } = await this.interface.chooseImage({ //上面封装的选择图片方法 count: 1, sourceType: sourceType || undefined, }); if(!assets) { return; } this.setState({ imageUploading: true, }); const res = await this.apiClient.uploadFile(assets[0].uri) //上面封装的七牛上传方法 if(res && res.url && this.singleEditInd){ images[this.singleEditInd] = res.url } this.setState({ images: [...images], imageUploading: false, }, this.handleChange ); } private handleChooseVideo = async(sourceType?: 'camera') => { const { onChange } = this.props let { imageUploading } = this.state; if (imageUploading) { return; } const { assets } = await this.interface.chooseVideo({ sourceType: sourceType }); if(!assets) { return; } this.setState({ imageUploading: true, }); const res = await this.apiClient.uploadFile(assets[0].uri) //上面封装的七牛上传方法 if(res && res.url){ //视频就不在组件中展示了,父组件处理 if(onChange) { onChange(res.url) } } this.setState({ imageUploading: false, }); } private handleDelete = (ind:number) => { let { images } = this.state images.splice(ind,1) this.setState({ images: [...images] }, this.handleChange ) } private handleChange = () => { const { onChange } = this.props const { images } = this.state if(onChange) { onChange(images) } }}
最后调用
import Uploader from "@/components/Uploader";... <Uploader count={6} onChange={urls => { this.setState({ uploadImgs: urls }) }} src={uploadImgs} />...
感谢各位的阅读,以上就是“react如何实现图片选择”的内容了,经过本文的学习后,相信大家对react如何实现图片选择这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!