当前位置: 首页 > news >正文

vue3 实现下载指令

// download.ts
/*** v-downLoad 下载文件*  */ 
export type DownloadBindingType = DownloadFile | string | string[];interface ElType extends HTMLElement {$destroyDownLoad?: () => void;$downLoadCallback?: () => void;$downLoadValue?: DownloadBindingType;
}export default {beforeMount(el: ElType,{value,arg,}: DirectiveBinding<((value?: DownloadBindingType) => void) | DownloadBindingType>,) {if (value instanceof Function && arg === 'callback') {el.$downLoadCallback = value;} else {el.$downLoadValue = value as DownloadBindingType;}const handler = async () => {if (el.$downLoadCallback && el.$downLoadValue instanceof Function) {el.$downLoadCallback();return;}if (Array.isArray(el.$downLoadValue)) {for (const val of el.$downLoadValue) {await (await downloadFile(val))();}} else {await (await downloadFile(el.$downLoadValue as DownloadFile))();}if (el.$downLoadCallback) {el.$downLoadCallback();}};el.addEventListener('click', handler);el.$destroyDownLoad = () => el.removeEventListener('click', handler);},// 当指令绑定的dom元素发生变化时触发updated(el: ElType,{value,arg,}: DirectiveBinding<((value?: DownloadBindingType) => void) | DownloadBindingType>,) {// 重新绑定if (value instanceof Function && arg === 'callback') {el.$downLoadCallback = value;} else {el.$downLoadValue = value as DownloadBindingType;}},beforeUnmount(el: ElType) {// 移除事件处理器、地址对象/回调函数el.$destroyDownLoad?.();delete el.$downLoadValue;delete el.$downLoadCallback;},
};interface DownloadFile {blob?: Blob;url?: string;fileName?: string;
}async function downloadFile(file: DownloadFile | string) {return async () => {let blob: Blob;let fileName: string;if (typeof file === 'string') {// 处理URL字符串blob = await fetchBlob(file);fileName = getFileNameFromUrl(file);} else if (file.blob instanceof Blob) {// 处理Blob对象blob = file.blob;fileName = file.fileName || 'download';} else if (file.url) {// 处理包含URL的对象blob = await fetchBlob(file.url);fileName = file.fileName || getFileNameFromUrl(file.url);} else {console.error('Invalid file format');return false;}const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = fileName;document.body.append(a);a.click();a.remove();URL.revokeObjectURL(url);return true;};
}async function fetchBlob(url: string): Promise<Blob> {import.meta.env.PROD && (url = url.replace(/^http:/, 'https:'));const response = await fetch(url);return await response.blob();
}function getFileNameFromUrl(url: string): string {const parts = url.split('/');let fileName = parts[parts.length - 1];// 移除查询参数fileName = fileName?.split('?')[0];// 如果有扩展名,移除扩展名// 如果没有文件扩展名,添加.pngif (!fileName?.includes('.')) {fileName += '.png';}if (fileName?.includes('.') &&!fileName.endsWith('.mp3') &&!fileName.endsWith('.mp4')) {fileName = fileName.replace(/\.\w+$/, '.png');}if (fileName) {return fileName;}return '';
}

 公共导出指令

// directive/index.ts
import downLoad from './download'; 
import type { App } from 'vue';// eslint-disable-next-line unicorn/no-anonymous-default-export
export default (app: App) => { app.directive('downLoad', downLoad); 
};

 注册指令

//main.ts
import App from './App.vue';
import directive from './directive';
const app = createApp(App);
// 注册自定义指令
directive(app);

使用指令进行下载

// 下载图片
<el-buttonclass="flex-1"size="large"type="primary"v-downLoad="{url: imgContent.image,fileName: `${imgContent.title}.png`,}"
>下载图片
</el-button>
// 下载视频
<div
v-downLoad="{url: item.video_url,fileName: `${item.createTime}.mp4`,
}"
>
<el-icon color="#556477" size="24px"><ep-Download />
</el-icon>
</div>

http://www.lryc.cn/news/604943.html

相关文章:

  • 【通识】操作系统
  • Python 程序设计讲义(45):组合数据类型——集合类型:集合的常用操作
  • jni理解
  • 网络编程-(网络计算机和网络通信)
  • Adobe Illustrator安装下载教程(附安装包)Illustrator2025
  • 【异世界历险之数据结构世界(冒泡、选择、快速排序)】
  • 数据结构(7)单链表算法题OVA
  • LLM 模型部署难题的技术突破:从轻量化到分布式推理的全栈解决方案
  • 【数据结构初阶】--二叉树(五)
  • 数据结构——单链表1
  • jmeter读取上游接口并遍历数组数据并进行压测
  • Vulnhub靶场:ica1
  • 【网络运维】 Linux:使用 Cockpit 管理服务器
  • IO复用实现并发服务器
  • 2025年7月技术问答第6期
  • 无人机入门--个人笔记
  • 电力设施通道防外破防异物实时监控预警装置的核心功能是什么
  • C 语言与 C++、Java、Python 等编程语言的区别
  • 国产音频DA转换芯片DP7361支持192K六通道24位DA转换器
  • Android RTMP推送|轻量级RTSP服务同屏实践:屏幕+音频+录像全链路落地方案
  • 工业计算机ARM-如何实现工业数字化升级EC100!
  • 论文阅读|NeurIPS 2024|Mamba进一步研究|MSVMamba
  • 原生微信小程序实现语音转文字搜索---同声传译
  • NAT技术与代理服务
  • SNR-Aware Low-light Image Enhancement 论文阅读
  • 【网络工程师软考版】路由协议 + ACL
  • 15、点云<—>深度图转换原理
  • rabbitmq--默认模式(点对点)
  • 【深度学习新浪潮】3D城市建筑多样化生产的研发进展调研
  • vulhub-Thales靶机练习