当前位置: 首页 > Web前端 > JavaScript

只需要一百或十行代码就可以为您的网页添加本地文件操作功能,你确定不想试试吗?

时间:2023-03-26 22:37:17 JavaScript

作者开源了一个网络思维导图思维导图。默认情况下,数据存储在localstorage中。如果要保存到本地文件,需要使用导出功能。下次打开它时,您可以使用导入功能。编辑完成后,如果要保存到文件中,需要重新导出并覆盖原文件。不得不说,可以但不优雅,所以最近加了直接编辑本地文件的功能。稍微体验了一下,还是不错的,只是调整一下API而已。这很简单,何乐而不为呢。主角是showOpenFilePicker和showSaveFilePicker这两个API。作者基于它们开发了三个功能:New和SaveAs其实是一样的,只是一个保存空数据,一个保存当前数据。当文件创建或打开成功,操作时,数据会直接保存到本地文件中,无需手动导出,这个体验其实和本地编辑没什么区别。让我们先看一下打开文件。调用showSaveFilePicker方法,并返回一个Promise。如果文件选择成功,Promise的结果是一个数组,每一项代表一个文件的操作句柄:如果要获取一个文件的内容或者写入一个文件,需要传递这些文件处理对象。如果没有选择或者选择失败Promise会报错:该方法接收一个options对象作为参数:options.multiple布尔值,设置是否可以选择多个文件。options.types是一个数组,它设置了允许选择的文件类型。数组中的每一项都是一个object:{description:'',accept:{'':[]}}description是用来描述的,好像没什么用,accept是一个Object,key是MIME类型,value是一个数组,表示允许的文件扩展名。如果MIME类型设置的很具体,比如application/json,那么如果不传值,只能选择文件后缀为.json的文件。如果该值设置了扩展名,也可以选择除了默认的.json文件之外的设置对于带有扩展名的文件,比如设置为['.smm'],则为.json文件和.smm后缀可以选择:如果MIME类型设置的比较宽泛,比如application/*,那么所有的MIME类型都是application类型所有的文件都可以选择,即使value只设置了一个.json,其他类型的文件也可以选择,所以value的功能不是限制,而是扩展。但是,这个限制很容易被突破。只需单击扩展名即可打开下拉列表并选择所有文件选项。然后你可以选择你想要的任何文件。有知道怎么解决的欢迎在评论区留言。options.excludeAcceptAllOption布尔值,默认为false,即允许不配置types选项,支持选择所有文件。如果设置为true,则types选项不能为空,并且必须限制文件类型。作者的思维导图文件格式是.json,我自己定义了一个格式。fileHandle=nullasyncopenLocalFile(){try{let[_fileHandle]=awaitwindow.showOpenFilePicker({types:[{description:'',accept:{'application/json':['.smm']}},],excludeAcceptAllOption:真,多个:假});if(!_fileHandle){return}fileHandle=_fileHandleif(fileHandle.kind==='directory'){this.$message.warning('Pleaseselectafile')return}这个。readFile()}catch(error){if(error.toString().includes('aborted')){return}this.$message.warning('您的浏览器可能不支持')}}保存后的文件句柄它,文件将在未来基于它进行操作。我们先来看看文件句柄对象。它有两个方法:getFile()返回一个Promise来获取句柄对应的文件对象,其实就是我们常见的File对象:createWritable()的返回也是一个Promise,创建一个可以写入文件的文件流对象:基于这两个方法,我们可以读取打开文件的内容,并将新内容写入文件://读取文件asyncreadFile(){letfile=awaitfileHandle.getFile();让fileReader=newFileReader();fileReader.onload=async()=>{//fileReader.result}fileReader.readAsText(file);}//写入文件asyncwriteLocalFile(content){if(!fileHandle){return;}让string=JSON.stringify(content);constwritable=awaitfileHandle.createWritable();等待writable.write(string);awaitwritable.close();}page第一次调用createWritable方法时,浏览器会弹出一个窗口询问用户权限:每次调用createWritable方法都会在本地创建一个.crswap文件:它相当于一个临时文件,在调用writestreamwritable的close方法之前,调用它的write方法写入的内容默认保存在这个文件中。只有调用close后才会更新到源文件,这个临时文件会自动删除。另外,当页面关闭时,这些文件也会被删除。写入流默认为空。是的,每次调用write方法,内容都会追加到.crswap中,但是可以指定write的位置:awaitwritable.write({type:"write",position:0,data:string});这会从指定的字节数开始写入,注意是替换,不是插入。所以为了方便,最好先创建,写入关闭,再写入再创建。新的调用是showSaveFilePicker方法,它还接收一个选项对象作为参数。有两个选项与showOpenFilePicker方法相同,分别是types和excludeAcceptAllOption。另外还有一个选项:suggestedName是默认填写的文件名,为空则创建。输入文件时输入框为空。您可以直接输入文件名来创建新文件,也可以单击现有文件来替换它。创建成功后还会返回一个文件句柄,所以创建文件非常简单:json':['.smm']},}],suggestedName:'思维导图'});如果(!_fileHandle){返回;}constloading=this.$loading({lock:true,text:'Creatingfile',spinner:'el-icon-loading',background:'rgba(0,0,0,0.7)'});文件句柄=_文件句柄;等待this.writeLocalFile(content);等待this.readFile();加载.close();}catch(error){if(error.toString().includes('aborted')){return}this.$message.warning('您的浏览器可能不支持');}}看一下实际效果:总结最后看一下兼容性:因为还在实验中,可以看出是一片红色,但是因为我的本身只是一个sampleproject,所以是不是什么大问题,总比没有好。此外,该功能目前仅在HTTPS协议或localhost下可用。其他情况下,window对象没有这两个API,需要处理错误。