笔者开源了一个Web思维导图mind-map,数据默认是存储在localstorage里,如果想保存到本地文件,需要使用导出功能,下次打开再使用导入功能,编辑完如果又想保存到文件,那么又需要从重新导出覆盖原来的文件,不得不说,可以但不优雅,所以最近增加了直接编辑本地文件的能力,体验了一下,还是不错的,并且就是调调API的事情,很简单,何乐而不为。 主角就是showOpenFilePicker和showSaveFilePicker两个API,笔者基于它俩开发了三个功能:
新建和另存为其实一样的,只不过一个保存的是空数据,一个是当前的数据,当创建或打开文件成功后,操作的时候数据会直接保存到本地文件里,不再需要进行手动的导出,这种体验其实就和本地编辑器没什么区别了。 打开 先来看看打开文件,调用的是showSaveFilePicker方法,返回一个Promise,选择文件成功了那么Promise的结果是一个数组,每一项代表一个文件的操作句柄:
如果要获取某个文件的内容或写入某个文件就需要通过这些文件句柄对象。如果没有选择或选择失败了Promise则会出错:
这个方法接收一个选项对象作为参数:
options.multiple
布尔值,设置是否可以选择多个文件。
options.types
一个数组,设置允许被选择的文件类型,数组每一项都是一个对象: { description: '', accept: { '': [] } } 复制代码 description用于说明,好像没什么用,accept是个对象,key为MIME type,value为一个数组,代表允许的文件扩展名。 如果MIME type设置的很具体,比如application/json,那么value不传的话只能选择文件后缀为.json的文件,如果value设置了扩展名的话,则在默认的.json文件外还允许选择设置的扩展名的文件,比如设置为['.smm'],那么.json和.smm为后缀的文件都可以选择:
如果MIME type设置的比较宽泛的话,比如application/*,那么所有MIME type为application类型的文件都可以选择,就算value只设置了一个.json,其他类型的文件也是可以选择的,所以value的作用不是限制,而是扩充。 但是呢,这种限制可以轻松突破,只要点击扩展名打开下拉列表选择所有文件选项,那么还是想选什么文件就选什么文件,有朋友知道怎么解决的欢迎评论区留言。
options.excludeAcceptAllOption
布尔值,默认为false,即允许不配置types选项,支持选择所有文件,如果设为true,那么types选项不能为空,必须要限制一种文件类型。 笔者的思维导图文件格式使用的是.json,并且吃饱了撑的自己定义了一个格式.smm,其实就是json,并且同一时间只能编辑一个文件,那么打开文件的代码如下所示: let fileHandle = null async openLocalFile() { try { let [ _fileHandle ] = await window.showOpenFilePicker({ types: [ { description: '', accept: { 'application/json': ['.smm'] } }, ], excludeAcceptAllOption: true, multiple: false }); if (!_fileHandle) { return } fileHandle = _fileHandle if (fileHandle.kind === 'directory') { this.message.warning('请选择文件') return } this.readFile() } catch (error) { if (error.toString().includes('aborted')) { return } this.message.warning('你的浏览器可能不支持哦') } } 复制代码 将文件句柄保存起来,接下来都会基于它来操作文件,先来看看文件句柄对象,它存在两个方法:
作者:街角小林 链接:juejin.cn/post/715768… 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。