<template>
<div class="imgUploader">
<div class="file-list">
<section
v-for="(file, index) in imgStore" :key="index"
class="file-item draggable-item"
>
<img :src="file.src" alt="" ondragstart="return false;">
<span class="file-remove" @click="remove(index)">+</span>
</section>
<section class="file-item" v-if="imgStatus !== 'finished'">
<div class="add">
<span>+</span>
<input type="file" pictype='30010003' multiple
data-role="none" accept="image/*"
@change="selectImgs"
ref="file"
>
</div>
</section>
</div>
<div class="uploadBtn">
<section>
<span v-if="imgStore.length > 0" class="empty"
@click="empty">
{{imgStatus === 'finished' ? '重新上传' : '清空'}}
</span>
</section>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
props: ['url'],
data () {
return {
files: [], // 文件缓存
index: 0 // 序列号
}
},
computed: {
...mapState({
imgStore: state => state.imgstore.img_upload_cache,
imgPaths: state => state.imgstore.img_paths,
imgStatus: state => state.imgstore.img_status
})
},
methods: {
// 选择图片
selectImgs () { # ①
let fileList = this.$refs.file.files
for (let i = 0; i < fileList.length; i++) {
// 文件过滤
if (fileList[i].name.match(/.jpg|.gif|.png|.bmp/i)) {
let item = {
key: this.index++,
name: fileList[i].name,
size: fileList[i].size,
file: fileList[i]
}
// 将图片文件转成BASE64格式
let reader = new FileReader() # ②
reader.onload = (e) => {
this.$set(item, 'src', e.target.result)
}
reader.readAsDataURL(fileList[i])
this.files.push(item)
this.$store.commit('set_img_upload_cache', this.files) // 存储文件缓存
this.$store.commit('set_img_status', 'selected') // 更新文件上传状态
}
}
},
// 上传图片
submit () {
let formData = new FormData() # ③
this.imgStore.forEach((item, index) => {
item.name = 'imgFiles[' + index + ']' # ④
formData.append(item.name, item.file)
})
formData.forEach((v, k) => console.log(k, ' => ', v))
// 新建请求
const xhr = new XMLHttpRequest() # ⑤
xhr.open('POST', this.url, true)
xhr.send(formData)
xhr.onload = () => {
if (xhr.status === 200 || xhr.status === 304) {
let datas = JSON.parse(xhr.responseText)
console.log('response: ', datas)
// 存储返回的地址
let imgUrlPaths = new Set() # ⑥
datas.forEach(e => { // error === 0为成功状态
e.error === 0 && imgUrlPaths.add(e.url)
})
this.$store.commit('set_img_paths', imgUrlPaths) // 存储返回的地址
this.files = [] // 清空文件缓存
this.index = 0 // 初始化序列号
this.$store.commit('set_img_status', 'finished') // 更新文件上传状态
} else {
alert(`${xhr.status} 请求错误!`)
}
}
},
// 移除图片
remove (index) {
this.files.splice(index, 1)
this.$store.commit('set_img_upload_cache', this.files) // 更新存储文件缓存
},
// 清空图片
empty () {
this.files.splice(0, this.files.length)
this.$store.commit('set_img_upload_cache', this.files) // 更新存储文件缓存
this.$store.commit('set_img_paths', [])
}
},
beforeCreate () {
this.$store.commit('set_img_status', 'ready') // 更新文件上传状态
},
destroyed () {
this.$store.commit('set_img_upload_cache', [])
this.$store.commit('set_img_paths', [])
},
watch: {
imgStatus () {
if (this.imgStatus === 'uploading') {
this.submit() # ⑦
}
},
imgStore () {
if (this.imgStore.length <= 0) {
this.$store.commit('set_img_status', 'ready') // 更新文件上传状态
}
}
}
}
</script>
<style lang="less" scoped>
...
</style>