上传自定义模板,上传成功和失败状态的自定义模板用不了
来源:9-5 Uploader 组件第三部分:自定义模版
qq_稻草人_81
2021-05-03
这里是上传组件:
<template>
<div class="file-upload">
<div class="file-upload-container" @click.prevent="triggerUpload">
<slot v-if="fileStatus === 'loading'" name="loading">
<button class="btn btn-primary" disabled>正在上传...</button>
</slot>
<solt v-else-if="fileStatus === 'sucess'" name='uploaded' :uploadData="uploadData">
<button class="btn btn-primary">上传成功</button>
</solt>
<solt v-else-if="fileStatus === 'error'" name='error'>
<button class="btn btn-primary" >上传失败</button>
</solt>
<slot v-else name="default">
<button class="btn btn-primary">上传文件</button>
</slot>
</div>
<input type="file"
class="file-input d-none"
ref="fileInput"
@change="handleFileChange">
</div>
</template>
<script lang='ts'>
/* 上传文件,自定义模板 */
import {defineComponent,ref,PropType} from 'vue'
import axios from '@/api/request'
// 定义上传的状态
type UploaderStatus = 'ready' | 'loading' | 'sucess' | 'error'
// 自定义检查,是一个函数,返回的是布尔值
type checkFunction = (file: File) => boolean
export default defineComponent({
props: {
action: {
type:String,
required: true
},
/* 上传前的一系列检查 */
boforeUpload: {
type: Function as PropType<checkFunction>
}
},
// 定义要暴露的上传成功事件,上传失败事件
emits: ['file-uploaded','file-uploaded-error'],
setup(props,context){
// 绑定ref,获得input元素的节点
const fileInput = ref<null | HTMLInputElement>(null)
// 定义返回出去的数据
const uploadData = ref()
// 创建上传状态的响应式对象
const fileStatus = ref<UploaderStatus>('ready')
const triggerUpload = () => {
//当input节点存在的时候,就触发点击事件
if (fileInput.value) {
fileInput.value.click()
}
}
// input 的change事件
const handleFileChange = ((e:Event) => {
// 获取里面的文件,这样是为了获得file属性
const currentTarget = e.target as HTMLInputElement
// 如果条件为真,说明已经选择了文件,可以上传
if (currentTarget.files) {
// 因为currentTarget.files不是一个数组,需要手动转换
const fiels = Array.from(currentTarget.files)
// 如果存在该属性,就做上传前的一系列检查
if (props.boforeUpload) {
const result = props.boforeUpload(fiels[0])
// 如果不满足条件,就不执行下面的程序
if (!result) {
return
}
}
fileStatus.value = 'loading'
const formData = new FormData
formData.append('file',fiels[0])
axios.post(props.action ,formData,{
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(res => {
fileStatus.value = 'sucess'
// 上传成功后,暴露成功事件
uploadData.value = res.data
context.emit('file-uploaded',res.data)
}).catch(err => {
fileStatus.value = 'error'
context.emit('file-uploaded-error',{err})
}).finally(() => {
if (fileInput.value) {
fileInput.value.value = ''
}
})
}
})
return {
fileInput,
triggerUpload,
handleFileChange,
fileStatus,
uploadData
}
}
})
</script>
<style>
</style>
这里是使用上传组件的页面:
<template>
<div>
<Uploader action="/upload"
:boforeUpload="boforeUpload"
@file-uploaded="onFileUploaded"
@file-uploaded-error="onfileUploadedError">
<template #loading>
<span>正在上传中。。。</span>
</template>
</Uploader>
<column-list :list="testData"></column-list>
</div>
</template>
<script lang='ts'>
/* 使用上传文件,自定义模板 */
import {defineComponent,computed,onMounted} from 'vue'
import ColumnList from '@/components/ColumnList/ColumnList.vue'
import {useStore} from 'vuex'
import {GlobalDataProps,ResponseType,ImageProps} from '@/store/index'
import Uploader from '@/components/Uploader/Uploader.vue'
import createMessage from '@/hooks/createMessage'
export default defineComponent({
components: {
ColumnList,
Uploader
},
setup(){
// 为了能够更好的提示,我们这里使用泛型
const store = useStore<GlobalDataProps>()
onMounted(() => {
// 经过此方式,把请求到的数据赋值给columns
store.dispatch('fetchColumns')
})
// 然后
const list = computed(()=> store.state.columns)
// 做上传前的一系列检查
const boforeUpload = (file:File) => {
const isPng = file.type == 'image/png'
if (!isPng) {
createMessage('上传文件格式不是png','error')
}
return isPng
}
// 上传成功
const onFileUploaded = (rawData:ResponseType<ImageProps>) => {
console.log('上传成功了:',rawData);
createMessage(`上传图片ID ${rawData.data._id}`,'success')
}
// 上传失败
const onfileUploadedError = (err:ResponseType<ImageProps>) => {
console.log('err',err);
const msg = err.msg || '上传路径错误'
createMessage(`上传文件 ${msg}`,'error')
}
return {
testData:list,
boforeUpload,
onFileUploaded,
onfileUploadedError
}
}
})
</script>
<style>
</style>
在使用上传组件的页面,只有状态为ready和loading自定义模板才生效,上传状态为成功和失败却不行,不知道哪里出现了问题?
写回答
3回答
-
同学你好 找到问题了 你的拼写错误了~ 下次请细心一点~
// uploader.vue 第七行 <slot> 你拼写成了 <solt> 第十行的问题是一样的
012021-05-05 -
张轩
2021-05-05
同学你好 我下载使用了 发现这个问题已经解决了是吗?
012021-05-05 -
张轩
2021-05-04
同学你好 能否辛苦你提供一下源代码吗?(git) 我在本地帮你看一下
032021-05-04
相似问题