Preview zip in vue (full version)

The zip data stream is obtained from the back-end interface in blob form, and the plug-in jszip is used to extract the directories in the zip and bind them to a-tree.

At the same time, the icon in the tree is modified according to the type of the file in the compressed package, and the style is modified to make the display clearer.

1. Add jszip plug-in:

yarn add jszip

(I usually use yarn to add, it is very stable and fast when adding, and there are few problems)

2. Since only a certain page in my project uses this function, I use local reference:

Introduced on the page where this function is used:

import JSZip from ‘jszip’

3. For page design, I used a-tree to display, mainly using treeData data:

The format is as follows:

const treeData = [
   {
     title: "root",
     key: "",
     scopedSlots: { icon: "folder" },
     children: [
      {
        title: "folder1",
        key: "0-1",
        id:"0-1",
        parentId:"",
        scopedSlots: { icon: "folder" },
        children: [
          { title: "1.txt", key: "0-1-1", parentId: "0-1", scopedSlots: { icon: "txt" } },
          { title: "3.png", key: "0-1-2", parentId: "0-1", scopedSlots: { icon: "png" } },
          { title: "2.xml", key: "0-1-3", parentId: "0-1", scopedSlots: { icon: "xml" } },
        ],
      },
      {
        title: "folder2",
        key: "0-2",
        id:"0-2",
        parentId:"",
        scopedSlots: { icon: "folder" },
        children: [
          { title: "7.xlsx", key: "0-2-1", parentId: "0-2", scopedSlots: { icon: "childEdit" } },

        ],
      },
      {
        title: "6.pdf",
        key: "0-3",
        id:"0-3",
        parentId:"",
        scopedSlots: { icon: "pdf" },
      },
  ],
 },
];

The html of a–tree is as follows:

<a-tree
                  showIcon
                  :default-expanded-keys="expandedKeys"
                  :expandedKeys="expandedKeys"
                  :selectedKeys="selectedKeys"
                  :treeData="treeData"
                  @expand="onExpand"
                  @select="onSelect"
                >
                <a-icon slot="folder" class="folder" type="folder" />
                <a-icon slot="image" class="image" type="file-image" />
                <a-icon slot="audio" class="audio" type="audio" />
                <a-icon slot="video" class="video" type="video-camera" />
                <a-icon slot="docx" class="docx" type="file-word" />
                <a-icon slot="xml" class="xml" type="file-excel" />
                <a-icon slot="pdf" class="pdf" type="file-pdf" />
                <a-icon slot="zip" class="zip" type="file-zip" />
                <a-icon slot="txt" class="txt" type="file-text" />
              </a-tree>

The styles are as follows, which can be modified at will:

#ziptree .anticon{
  font-size: 20px; color: #08c
}
#ziptree .anticon.folder{
   color: #e7c146
}
#ziptree .anticon.docx{
   color: #2a0ae2
}
#ziptree .anticon.pdf{
   color: #e90b1e
}
#ziptree .anticon.xml{
   color: #047449
}
#ziptree .anticon.zip{
   color: #435892
}
#ziptree .anticon.txt{
   color: #b9c6e7
}
#ziptree .anticon.image{
   color: #82c0a8
}

4. Obtain data through the interface and process the data:

 downloadAttachmentStream(option).then((res)=>{
                        if (!res & amp; & amp; res.status!=200 & amp; & amp; res.data.type == "application/json") {
                            this.$message.error('The file cannot be found')
                            return
                        }
                          
                        let jszip = new JSZip()
                        jszip.loadAsync(res.data).then(zip=>{

                          let myData=[]
                          that.transformData(zip, myData,0,)
                          that.treeData=myData
                          that.$nextTick(()=>{
                            that.expandedKeys=['0']
                          })
                        })
                    });

The transformData method is as follows:

 transformData(obj, myData, level = 0) {
      let id=0
      if(Object.keys(obj.files).length==0){
        let fname=this.fileName.substring(0, this.fileName.lastIndexOf("."))
        let rootData={id:'0',parentId:'', key:'0',title:fname, fullName:fname + '/' ,type:'dir', children:[],slots:{ icon: " folder" }}
        myData.push(rootData)
      }else{
      for (let key in obj.files) {
        let array=key.split('/').filter(item => item != '')
        if(array.length == level + 1){
          if (obj.files[key].dir) {
            if(level==0){ // There is only one root
              let rootData={id:'0',parentId:'', key:'0',title:array[level], fullName:key ,type:'dir', children:[],slots:{ icon: "folder " }}
              myData.push(rootData)
              this.transformData(obj, rootData,level + 1)
            }else{
              // non-root directory
              if(key.indexOf(myData.fullName)===0 & amp; & amp; key!= myData.fullName & amp; & amp; array.length == level + 1){
              let newData={id:myData.id + '-' + id, key:myData.id + '-' + id,parentId:myData.id, title:array[level], type:'dir', children:[ ],fullName:key,slots:{ icon: "folder" }}
              myData.children.push(newData)
              id++
              this.transformData(obj, newData,level + 1)
              }
            }
          }else{ // file
           if(key.indexOf(myData.fullName)==0 & amp; & amp; key!=myData.fullName){
            let data= {id:myData.id + '-' + id,parentId:myData.id, key:myData.id + '-' + id,title:array[level], type:array[level].replace( /. + \./, ""),fullName:key,}
             if(['jpg','png','gif'].includes(data.type)){
              data.slots={icon: "image"}
             }else if(data.type=='mp3'){
               data.slots={icon: 'audio'}
             }else if(data.type=='mp4'){
               data.slots={icon: 'video'}
             } else if(data.type=='xlsx'){
               data.slots={icon: 'xml'}
             } else{
              data.slots={icon: data.type}
             }
             myData.children.push(data)
             id++
           }
          }
        }else{
          //
        }
      }
      }
      return myData;
    },

After the above steps, you can achieve a beautiful directory tree of the compressed package.