前言在我们日常开发vue或者react项目中,或多或少都会遇到这样一个需求:我想在某个页面加载一个外部资源文件,比如百度地图的js文件,确定文件加载后还要执行一些逻辑。这些第三方文件往往只在一个场景中使用,并不想全局放置。这时候就需要实现一个文件的动态加载器。代码不多说,先上代码://如果没有传入类型,则根据url的后缀判断类型constgetTypeFromUrl=url=>{const_type=/\.[^.]+$/.exec(url)[0];if(_type==='.js'){返回'text/javascript';}if(_type==='.css'){return'text/css';}}//formatpass输入文件列表constformatFileList=file=>{letlist;if(typeoffile==='string'){list=[file];}elseif(Array.isArray(file)){list=file;}else{throw{error:'参数必须是字符串或数组'};}让格式列表;formatList=list.map((i)=>{leturl;lettype;if(typeofi==='string'){url=i;type=getTypeFromUrl(url);}elseif(Array.isArray(i)){[url]=i;type=(i[1]&&i[1].type)?i[1].type:getTypeFromUrl(url);}else{throw{error:'参数必须是一个字符串或数组'};}if(!type){throw{error:'URL类型未知'};}返回{url,类型};});returnformatList;}//根据类型创建元素constcreateElement=({type,url})=>{switch(type){case'text/javascript':{constelement=document.createElement('script');element.setAttribute('type','text/javascript');元素.src=url;返回元素;}case'text/css':{constelement=document.createElement('link');元素.href=url;element.setAttribute('rel','stylesheet');element.setAttribute('媒体','全部');element.setAttribute('type','text/css');返回元素;默认值:中断;}}//加载文件constloadElement=element=>newPromise((resolve)=>{consthead=document.getElementsByTagName('head')[0];head.appendChild(element);if(element.readyState){element.onreadystatechange=()=>{if(element.readyState==='loaded'||element.readyState==='complete'){element.onreadystatechange=null;解决();}};}else{element.onload=resolve;}});constdynamicFile=异步文件=>{try{constlist=formatFileList(file);常量元素列表=列表。地图(创建元素);等待承诺。all(elementList.map((i)=>{returnloadElement(i);}));}赶上(错误){console.log(错误);}}//单例防止重复加载constcreateSingle=fn=>{constinstanceMap={};返回函数(){返回instanceMap[arguments[1]]||(instanceMap[arguments[1]]=fn.apply(this,arguments));}}导出默认createSingle(dynamicFile);如何使用方法传入一个数组和一个字符串类型的名字,名字相当于一个标志,如果名字相同,这个页面加载后,如果其他页面也有相同的名字,资源文件不会反复加载,分不清是js还是css,需要手动指定类型。如果url后缀是.js或者.css,可以省略这个参数。dynamicImport([['http://api.map.baidu.com/api?v=2.0&ak=VcIKGv3f9eq712B7idam46dd6in2fg8R&callback=baiduMap',{type:'text/javascript'}],['http://api.map.baidu.com/getscript?v=2.0&ak=VcIKGv3f9eq712B7idam46dd6in2fg8R&services=&t=20210225162129',{type:'text/javascript'}]],'baiduMap').then(()=>{letmap=newBMap.Map('myMap');letpoint=newBMap.Point(116.397128,39.916527);map.centerAndZoom(point,6);map.enableScrollWheelZoom();})如果只有一个文件,后缀为.js或者.css,你可以简写:dynamicImport('https://cdn.bootcdn.net/ajax/libs/Chart.js/3.7.0/chart.min.js','chart').then(()=>{constctx=document.getElementById('myChart').getContext('2d');...})最后,我是前端小伙伴周晓阳。写文章记录自己在日常工作中遇到的问题和学到的东西,以提高自己,如果觉得这篇文章对你有用,请点个赞鼓励一下~
