import Vue from 'vue' ; import { createNamespace } from '../../utils' ; import uploadAjax from './upload' ; import Toast from '../toast' ; export type UploadProps = { action : string ; name : string ; data : any ; headers : any ; accept : string ; beforeUpload ( ) : void ; onSuccess ( ) : void ; onError ( ) : void ; disabled : boolean ; multiple : boolean ; maxSize : number ; exceedMaxSizeText : string ; maxCount : number ; withCredentials : boolean ; capture : string ; } ; const [ createComponent , bem , t ] = createNamespace ( 'upload' ) ; export default createComponent < UploadProps > ( { props : { action : { type : String , default : '' , required : true , } , name : { type : String , default : 'Filedata' , } , data : Object , headers : Object , accept : { type : String , default : '' , } , beforeUpload : { type : Function , default : ( ) => { } , } , onSuccess : { type : Function , default : ( ) => { } , } , onError : { type : Function , default : ( ) => { } , } , disabled : { type : Boolean , default : false , } , multiple : { type : Boolean , default : false , } , maxSize : { type : Number , default : 0 , } , exceedMaxSizeText : { type : String , default : t ( 'exceedText' ) , } , maxCount : { type : Number , default : 10 , } , withCredentials : { type : Boolean , default : false , } , capture : { type : String , default : null , } , } , data ( ) { return { uploadAjax , } ; } , methods : { handleClick ( this ) { if ( this . disabled ) { return false ; } this . $refs . input . click ( ) ; } , handleChange ( this , e ) { const files = e . target . files ; if ( ! files . length ) { return ; } let postFiles = Array . prototype . slice . call ( files ) ; this . $refs . input . value = null ; if ( ! files || ! postFiles . length ) { return false ; } if ( ! this . multiple ) { postFiles = postFiles . slice ( 0 , 1 ) ; } if ( this . multiple && this . maxCount ) { postFiles = postFiles . slice ( 0 , this . maxCount ) ; } const fileLength = postFiles . length ; postFiles . forEach ( ( file , index ) => { file . index = index ; file . total_length = fileLength ; this . uploadFile ( file ) ; } ) ; } , wrapperUploadAjax ( this , options ) { Vue . nextTick ( ( ) => { Object . assign ( options , { headers : this . headers , withCredentials : this . withCredentials , data : this . data , filename : this . name , action : this . action , onProgress : ( ) => { } , onSuccess : res => { this . onSuccess ( res , options . file , this ) ; } , onError : err => { this . onError ( err , options . file , this ) ; } , } ) ; this . uploadAjax ( options ) ; } ) ; } , uploadFile ( this , file ) { const options = { file , } ; if ( this . maxSize ) { const size = file . size ; if ( size > this . maxSize ) { Toast ( { type : 'fail' , duration : 1500 , message : this . exceedMaxSizeText , } ) ; return false ; } } if ( ! this . beforeUpload ) { this . wrapperUploadAjax ( options ) ; return ; } const beforeReturn = this . beforeUpload ( file , this ) ; if ( beforeReturn && beforeReturn . then ) { beforeReturn . then ( processedFile => { const toString = Object . prototype . toString ; if ( toString . call ( processedFile ) === '[object File]' ) { options . file = processedFile ; this . wrapperUploadAjax ( options ) ; } else { this . wrapperUploadAjax ( options ) ; } } , ( ) => { } ) ; } else if ( beforeReturn !== false ) { this . wrapperUploadAjax ( options ) ; } } , } , render ( this ) { const UploadSlot = this . slots ( ) || ( < div class = { bem ( 'upload-icon-box' ) } > < div class = { bem ( 'upload-icon' ) } > < svg viewBox = "0 0 20 20" fill = "none" xmlns = "http://www.w3.org/2000/svg" > < path fill - rule = "evenodd" clip - rule = "evenodd" d = "M11.25 1.25a1.25 1.25 0 10-2.5 0v7.5h-7.5a1.25 1.25 0 100 2.5h7.5v7.5a1.25 1.25 0 102.5 0v-7.5h7.5a1.25 1.25 0 100-2.5h-7.5v-7.5z" fill = "#D8D8D8" / > < /svg> < /div> < /div>); return ( < div class = { bem ( ) } > { this . multiple && ( < div onClick = { this . handleClick } > < input ref = "input" accept = { this . accept } disabled = { this . disabled } multiple = "multiple" type = "file" name = "Filedata" class = "_file-input" onChange = { this . handleChange } capture = { this . capture } / > { UploadSlot } < /div>)} { ! this . multiple && ( < div onClick = { this . handleClick } > < input ref = "input" accept = { this . accept } disabled = { this . disabled } type = "file" name = "Filedata" class = "_file-input" onChange = { this . handleChange } capture = { this . capture } / > { UploadSlot } < /div>)} < /div>); } , } ) ;