前言

周末逛github的时候,发现咱们只须要在github域名上加上1s他就可能关上一个vscode窗口来浏览代码,比起在github仓库中查看更加不便

而后我就想网页端vscode能不能关上我本地的我的项目呢,带着这个纳闷我关上了网页版vscode,它竟然真的能够关上我本地的我的项目代码!

难道又出了新的API让前端的能力更进一步了?关上MDN查了一下相干文档,发现了几个新的API

showOpenFilePicker

用来抉择文件

语法

showOpenFilePicker()

参数

  • options:(可选)蕴含以下属性

    • multiple:布尔值,默认为false。为true示意容许用户抉择多个文件
    • excludeAcceptAllOption:布尔值,默认为false。默认状况下,文件选择器带有一个容许用户抉择所有类型文件的过滤选项(开展于文件类型选项中)。设置此选项为 true 以使该过滤选项不可用。
    • types:示意容许抉择的文件类型的数组

返回值

返回一个promise对象,会兑现一个蕴含 FileSystemFileHandle 对象的 Array 数组。

体验

<template>  <div class="open_file" @click="openFile">关上文件</div></template><script setup lang="ts">const openFile = async () => {  const res = await window.showOpenFilePicker();  console.log(res);};</script>

默认只能关上一个文件,能够传入multiple:true关上多个文件

showDirectoryPicker

用来抉择目录

语法

属于浏览器全局办法,间接调用即可

showDirectoryPicker()

参数

  • options:(可选)蕴含以下属性

    • multiple:布尔值,默认为false。为true示意容许用户抉择多个文件
    • excludeAcceptAllOption:布尔值,默认为false。默认状况下,文件选择器带有一个容许用户抉择所有类型文件的过滤选项(开展于文件类型选项中)。设置此选项为 true 以使该过滤选项不可用。
    • types:示意容许抉择的文件类型的数组

返回值

返回一个promise对象,会兑现一个蕴含 FileSystemFileHandle 对象的 Array 数组。

体验

<template>  <div class="open_file" @click="openFile">关上文件</div>  <div class="open_file" @click="openDir">关上文件夹</div></template><script setup lang="ts">const openFile = async () => {  const res = await window.showOpenFilePicker({    // multiple: true,  });  console.log(res.length);};const openDir = async () => {  const res = await window.showDirectoryPicker();  console.log(res);};</script>

扩大

FileSystemFileHandle

FileSystemFileHandle提供了一些办法能够用来获取和操作文件

  • getFile:返回一个Promise对象,用于获取文件;
  • createSyncAccessHandle:返回一个FileSystemSyncAccessHandle对象,用于同步拜访文件;
  • createWritable:返回一个Promise对象,用于创立一个可写流,用于写入文件;

FileSystemDirectoryHandle

FileSystemDirectoryHandle对象是一个代表文件系统中的目录的对象,它同样提供了办法来获取和操作目录

  • entries:返回一个AsyncIterable对象,用于获取目录中的所有文件和目录;
  • keys:返回一个AsyncIterable对象,用于获取目录中的所有文件和目录的名称;
  • values:返回一个AsyncIterable对象,用于获取目录中的所有文件和目录的FileSystemHandle对象;
  • getFileHandle:返回一个Promise对象,用于获取目录中的文件;
  • getDirectoryHandle:返回一个Promise对象,用于获取目录中的目录;
  • removeEntry:返回一个Promise对象,用于删除目录中的文件或目录;
  • resolve:返回一个Promise对象,用于获取目录中的文件或目录;

entrieskeysvalues这三个办法都是用来获取目录中的所有文件和目录的,它们返回的都是一个AsyncIterable对象,咱们能够通过for await...of语法来遍历它。

开发编辑器

理解完这些知识点,咱们就能够来开发一个简陋网页版编辑器了,初期只蕴含关上文件、关上文件夹、查看文件、切换文件

编辑器大略长这样:

关上文件夹

const openDir = async () => {  const res = await window.showDirectoryPicker({});  const detalAction = async (obj: any) => {    if (obj.entries) {      const dirs = obj.entries();      for await (const entry of dirs) {        if (entry[1].entries) {          // 文件夹,递归解决          detalAction(entry[1]);        } else {          // 文件          fileList.value.push({            name: entry[0],            path: obj.name,            fileHandle: entry[1],          });        }      }    }  };  await detalAction(res);  showCode(fileList.value[0], 0);  console.log("--fileList--", fileList);};

这里次要是递归解决文件夹,返回一个文件列表

读取文件内容

const showCode = async (item: any, index: number) => {  const file = await item.fileHandle.getFile();  const text = await file.text();  codeText.value = text;  currentIndex.value = index;};

展现文件内容

应用highlight.js来高亮展现代码

<div class="show_code">  <pre v-highlight>        <code class="lang-dart">            {{ codeText }}        </code>   </pre></div>

最终成果如下:

想不到吧,这种性能当初纯前端就可能实现了,当然还能够做的更简单一点,包含批改保留等性能,保留能够应用showSaveFilePickerAPI,它能够写入文件,同样是返回一个promise。感兴趣的能够试着欠缺编辑器的性能。