• 使用@zip.js/zip.js与naive-ui的Tree组件实现在线文件解压预览


    zip.js

    用于压缩和解压缩文件的 JavaScript 库

    显着特点

    • 支持Zip64 格式
    • 支持WinZIP AES和 PKWare ZipCrypto 加密
    • 支持同时读取和写入一个或多个 zip 文件
    • 集成工作池管理器
    • 无第三方依赖

    该库依赖于PromiseTypedArray、 Streams API 以及以下可选的 API:

    兼容性

    该库与最新版本的 Chrome、Firefox、Safari、Microsoft Edge 和 Deno 完全兼容。

    Naive UI

    比较完整

    有超过 80 个组件,希望能帮你少写点代码。

    顺便一提,它们全都可以 treeshaking。

    主题可调

    我们提供了一个使用 TypeScript 构建的先进的类型安全主题系统。你只需要提供一个样式覆盖的对象,剩下的都交给我们。

    顺便一提,不用 less、sass、css 变量,也不用 webpack 的 loaders。以及你可以试试右下角的主题编辑器。

    使用 TypeScript

    Naive UI 全量使用 TypeScript 编写,和你的 TypeScript 项目无缝衔接。

    顺便一提,你不需要导入任何 CSS 就能让组件正常工作。

    我尽力让它不要太慢。至少 select、tree、transfer、table、cascader 都可以用虚拟列表。

    顺便一提,...,没有顺便了。祝你使用愉快。

    代码示例

    使用Upload组件上传文件

    1. <n-upload
    2. v-model:file-list="fileList"
    3. :show-file-list="true"
    4. :on-before-upload="onUpload"
    5. :on-remove="onRemove"
    6. accept="application/zip"
    7. list-type="image"
    8. max="1"
    9. >
    10. <n-upload-dragger>
    11. <div mb-2>
    12. <NIcon size="35" :depth="3" :component="Upload" />
    13. div>
    14. <div op-60>
    15. 点击选择,或将zip文件拽到此处
    16. div>
    17. n-upload-dragger>
    18. n-upload>
    19. import * as zip from '@zip.js/zip.js';
    20. const fileList = ref();
    21. const fileInput = ref() as Ref<File>;
    22. const allData = ref([]);
    23. const data = ref([]);
    24. async function onUpload({ file: { file } }: { file: UploadFileInfo }) {
    25. if (file) {
    26. fileInput.value = file;
    27. allData.value = [];
    28. const reader = new zip.ZipReader(new zip.BlobReader(file));
    29. const entries = await reader.getEntries();
    30. if (entries.length) {
    31. for (const entry of entries) {
    32. allData.value.push(formatFileEntry(entry));
    33. }
    34. }
    35. reader.close();
    36. let result = allData.value.filter(item => item.parent === '');
    37. if (!result.length) {
    38. result = allData.value.filter(item => item.level === 2);
    39. }
    40. data.value = result
    41. .map((item) => {
    42. return {
    43. label: item.fileName,
    44. key: item.fullFileName,
    45. isLeaf: !item.isDir,
    46. disabled: item.isDir,
    47. // children: [],
    48. ...item,
    49. };
    50. })
    51. .sort((a, b) => (a.isDir === b.isDir ? 0 : a.isDir ? -1 : 1));
    52. }
    53. }
    54. async function onRemove() {
    55. fileInput.value = null;
    56. allData.value = [];
    57. data.value = [];
    58. selectFile.value = null;
    59. }

    使用Tree组件显示文件列表

    1. <n-tree
    2. block-line
    3. :data="data"
    4. :on-load="handleLoad"
    5. :expanded-keys="expandedKeys"
    6. expand-on-click
    7. :render-prefix="renderPrefix"
    8. :render-suffix="renderSuffix"
    9. :render-label="renderLabel"
    10. :node-props="nodeProps"
    11. virtual-scroll
    12. style="max-height: 400px"
    13. @update:expanded-keys="handleExpandedKeysChange"
    14. @update:selected-keys="handleSelectedKeysChange"
    15. />
    16. <div v-if="selectFile" mt-5 flex justify-center>
    17. <c-button @click="downloadFile">
    18. 下载文件
    19. c-button>
    20. div>
    21. const expandedKeys = ref([]);
    22. function handleExpandedKeysChange(changeExpandedKeys: string[]) {
    23. expandedKeys.value = changeExpandedKeys;
    24. }
    25. function handleSelectedKeysChange(selectedKeys: string[], selectNodes: TreeOption[]) {
    26. selectFile.value = selectNodes[0];
    27. }
    28. async function handleLoad(node: TreeOption) {
    29. const result = allData.value.filter(item => item.parent === node.fullFileName);
    30. node.children = result
    31. .map((item) => {
    32. return {
    33. label: item.fileName,
    34. key: item.fullFileName,
    35. isLeaf: !item.isDir,
    36. disabled: item.isDir,
    37. // children: [],
    38. ...item,
    39. };
    40. })
    41. .sort((a, b) => (a.isDir === b.isDir ? 0 : a.isDir ? -1 : 1));
    42. }
    43. function renderPrefix({ option }: { option: TreeOption }) {
    44. if (option.isDir) {
    45. return h(NIcon, null, { default: () => h(Folder) });
    46. }
    47. return h(NIcon, null, { default: () => h(File) });
    48. }
    49. function renderSuffix({ option }: { option: TreeOption }) {
    50. return h('span', null, {
    51. default: () => {
    52. if (option.entry.uncompressedSize) {
    53. return formatBytes(option.entry.uncompressedSize);
    54. }
    55. else {
    56. return '';
    57. }
    58. },
    59. });
    60. }
    61. function renderLabel({ option }: { option: TreeOption }) {
    62. return h(NEllipsis, { tooltip: false }, { default: () => option.label });
    63. }
    64. async function downloadFile() {
    65. if (!selectFile.value) {
    66. return;
    67. }
    68. const dataUrl = URL.createObjectURL(await selectFile.value.entry.getData(new zip.BlobWriter(), {}));
    69. const a = document.createElement('a');
    70. a.href = dataUrl;
    71. a.download = selectFile.value.label;
    72. a.click();
    73. }

    效果可参考:

    在线ZIP解压工具 - BTool在线工具软件,为开发者提供方便。在线ZIP解压工具是一款便捷高效的云端压缩文件处理助手,无需下载安装任何软件,即可一键上传、在线解压ZIP格式的文件。它具备高速稳定、安全可靠的特点,完美支持大容量ZIP文件快速解压,让您随时随地轻松处理各类压缩文档,极大地提升了办公与学习效率。icon-default.png?t=N7T8https://www.btool.cn/unzip

  • 相关阅读:
    【配置文件】Redis配置文件解读和持久化
    图神经网络详细内容
    STM32如何将文件放到内部flash里面
    logback.xml springboot 项目通用logback配置,粘贴即用,按日期生成
    JavaScript 45 JavaScript 类型转换
    Flutter Json解析工具
    二分算法(超详细)
    教育课堂小程序,三分钟打造专属小程序 带完整搭建教程
    牛客训练3
    「区块链+数字身份」:DID 身份认证的新战场
  • 原文地址:https://blog.csdn.net/my565548320/article/details/136152436