vue2 + zip.js,网页预览zip压缩包

1,151 阅读1分钟

vue2 + zip.js(@2.7.6)

官方文档

最终效果

w6pmt-lapp9.gif

完整代码

<template>
  <div class="demo">
    <div class="fileTree">
      <el-tree 
        :data="zipData" 
        :props="defaultProps" 
        :highlight-current="true" 
        @node-click="handleNodeClick">
      </el-tree>
    </div>
    <div class="fileContent">
      {{ currentContent }}
    </div>
  </div>
</template>

<script>
const zip = require("@zip.js/zip.js/dist/zip.min.js");
  export default {
    data() {
      return {
        zipMap: {}, // 处理之后的压缩包数据
        zipData: [],
        currentContent: '',
        defaultProps: {
        children: 'children',
        label: 'label'
      },
      };
    },
    async created() {
      const myZip = await this.getZipFileBlob()
      this.loadZip(myZip)
    },
    methods: {
      // 模拟后端返回的压缩包文件流
      async getZipFileBlob() {
        const zipFileWriter = new zip.BlobWriter();
        const helloWorldReader = new zip.TextReader("api.js文件内容");
        const untils = new zip.TextReader("untils文件内容");
        const readMe = new zip.TextReader("readMe文件内容");
        const zipWriter = new zip.ZipWriter(zipFileWriter);
        await zipWriter.add("src/api/api.js", helloWorldReader);
        await zipWriter.add("src/untils.js", untils);
        await zipWriter.add("readMe", readMe);
        await zipWriter.close();
        const zipFileBlob = await zipFileWriter.getData();
        return zipFileBlob;
      },
      //解压
      async loadZip(e) {
        let zipMapTemp = {}; // 暂存压缩包数据,格式为{文件名1:内容1,文件名2:内容2}
        const zipFileReader = new zip.BlobReader(e);
        const helloWorldWriter = new zip.TextWriter();
        const zipReader = new zip.ZipReader(zipFileReader);
        const entries = await zipReader.getEntries();
        entries.forEach(async (entry, index) => {
            const writer = new zip.TextWriter();
            zipMapTemp[entry.filename] = await entry.getData(writer);
            if(index === entries.length - 1) {
                //entry.getData() 异步,在最后一个promise执行完之后,格式化zipMapTemp
                console.log('zipMapTemp',zipMapTemp)
                this.zipMap = this.convertToHierarchyObject(zipMapTemp)
                this.zipData = this.transformData(this.zipMap)
                console.log('zipData',this.zipData)
            }
        });
        await zipReader.close();
    },
    // 格式化
    convertToHierarchyObject(obj) {
      const hierarchy = {};
      for (let key in obj) {
        const parts = key.split('/');
        let currentLevel = hierarchy;
        for (let i = 0; i < parts.length; i++) {
          const part = parts[i];
          if (!currentLevel[part]) {
            if (i === parts.length - 1) {
              currentLevel[part] = obj[key];
            } else {
              currentLevel[part] = {};
            }
          }
          currentLevel = currentLevel[part];
        }
      }
      return hierarchy;
    },
    transformData(obj, level = 0) {
      const keys = Object.keys(obj);
      const data = keys.map(key => {
        if (typeof obj[key] === 'object') {
          return {
            label: key,
            children: this.transformData(obj[key], level + 1),
            level
          }
        } else {
          return {
            label: key,
            value: obj[key],
            level
          }
        }
      });
      return data;
    },
    handleNodeClick(node) {
      this.currentContent = node.value
    }
    }
  }
</script>
<style>
.demo {
  display: flex;
  flex-direction: row;
}
.fileContent {
  padding: 50px;
}
</style>

更详细的内容可以查看文档,此处截取官方文档读取压缩包代码

屏幕快照 2023-04-24 下午5.59.23.png

vue2 + JSZip(@3.10.1) 报错(未解决)

本来使用JSZip,可是偶发性报错如下,哪位大神解决了,求助!

屏幕快照 2023-04-24 下午6.29.54.png