
上篇文章从0搭建vue3组件库:Upload文件上传组件已经实现基本的文件上传组件,本篇文章将为Upload组件加入拖拽上传(drag)的功能。
首先在types.ts中定义一个drag来控制是否使用拖拽上传
import { ExtractPropTypes } from 'vue' export const uoloadType = { multiple: Boolean, accept: String, drag: Boolean } export type LinkProps = ExtractPropTypes
在upload.vue中通过判断用户是否传入drag来控制拖拽区域的显示与隐藏,并且为拖拽区域定义一些样式。部分代码省略,文章最后会贴最终完整代码
upload.vue部分代码将文件拖到此处或点击上传
style/index.less 部分代码.k-upload-dragger { background-color: #fff; border: 1px dashed #d9d9d9; border-radius: 6px; box-sizing: border-box; width: 360px; height: 180px; display: flex; cursor: pointer; align-items: center; justify-content: center; &:hover { border: 1px dashed #409eff; } .k-upload-content { text-align: center; color: #606266; .k-upload-icon { font-size: 20px; } em { color: #409eff; font-style: normal; } } }
然后在本地测试项目examples下的app.vue中引入
const getFilesList = (files: File[]) => { console.log(files) } " _ue_custom_node_="true">.upload-demo { width: 400px; } " _ue_custom_node_="true">
注意这里为了调试方便,已经全局导入了kitty-ui库了。对应的main.ts:
import { createApp } from 'vue' import App from './app.vue' const app = createApp(App) import kittyui from "kitty-ui" app.use(kittyui) app.mount('#app')
启动项目,便可以看到下面的效果

接下来要做的就是将文件拖进来获取到文件列表以及点击上传。其中点击上传很简单,只需要绑定和上面一样的事件即可
upload.vue部分代码将文件拖到此处或点击上传
实现拖拽上传可以借助drop事件。在组件生命周期onMounted中获取到拖拽区域的dom,然后监听它的drop事件。
首先给拖拽区域一个ref属性
将文件拖到此处或点击上传
然后在组件创建完成后进行事件监听
const fileArea = ref() onMounted(() => { fileArea.value.addEventListener('drop', (e: any) => { e.preventDefault(); console.log(e) }, false) fileArea.value.addEventListener('dragover', (e: any) => { e.preventDefault(); }, false) })
注意 这里需要阻止dragover的默认事件,不然drop是不生效的.此时我们将文件拖拽到这个区域后我们可以看到控制台打印很多东西,而我们只需要e.dataTransfer.files即可(不知道为什么控制台上显示files的长度为0,但是实际代码中却可以获取到)

获取到文件之后把文件名字渲染到下面的列表中,并且将文件列表传给用户,同时我们做个限制,如果没有传入drag则不监听这两个事件
const fileArea = ref() onMounted(() => { if (!props.drag) return fileArea.value.addEventListener('drop', (e: any) => { e.preventDefault(); filesList.value.push(...Array.from(e.dataTransfer.files as FileList)) emits('getFilesList', filesList.value) }, false) fileArea.value.addEventListener('dragover', (e: Event) => { e.preventDefault(); }, false) })
最终拖拽完毕的效果为

最后我们再加两个事件dragenter和dragleave来判断文件是否拖到这个区域从而展示不同样式
template 部分代码<div v-else class="k-upload-dragger" :class="{ ['k-upload-draggerenter']: isEnter }" ref="fileArea" @click="fileUpload"> 将文件拖到此处或点击上传
script部分代码const fileArea = ref() const isEnter = ref(false) onMounted(() => { if (!props.drag) return fileArea.value.addEventListener('drop', (e: any) => { e.preventDefault(); filesList.value.push(...Array.from(e.dataTransfer.files as FileList)) emits('getFilesList', filesList.value) }, false) fileArea.value.addEventListener('dragover', (e: Event) => { e.preventDefault(); }, false) fileArea.value.addEventListener('dragenter', (e: Event) => { isEnter.value = true e.preventDefault(); }, false) fileArea.value.addEventListener('dragleave', (e: Event) => { isEnter.value = false e.preventDefault(); }, false) })
此时文件进入的效果

到这里Upload组件拖拽上传的功能基本已经实现,如果大家对vue3组件库搭建感兴趣的话,欢迎大家关注 从零搭建Vue3组件库专栏 将持续更新一些组件的实现。
完整代码点击 kitty-ui 获取,最后希望大家给个
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者