VUE系列---VUE+indexDB+JSZip+在线预览zip压缩文件(三)

推荐我的vue教程:VUE系列教程目录

温馨连接提示:vue中级之路篇系列教程:
VUE系列---VUE+indexDB+JSZip+在线预览zip压缩文件(一)
VUE系列---VUE+indexDB+JSZip+在线预览zip压缩文件(二)
VUE系列---VUE+indexDB+JSZip+在线预览zip压缩文件(三)

注:请看完前两篇再来,不然你看不懂

通过前两篇文章我们的项目已经做出来了文件预览的初始效果,不知道你们看了以后会有什么想法,这篇文章开始着重讲解文件系统的构建。

前言

前面我们已经得到文件树对象了,现在我们所要做的就是页面的功能实现,我们读取并在indexDB数据库里存储了文件信息,为了解决直接渲染文件信息到页面上,浏览器崩溃的问题,我们没有直接进行读取,而是采用创建目录,进去了以后在打开某一个具体的文件时,读取这个具体文件这一个单独的文件时,这样读取的息量少,所以不会崩溃。

但是有个问题,我们怎么去取这个文件信息,或者说我们怎么在indexDB数据库里准确找到这个文件信息?因为indexDB的特殊性我们不能去遍历它,不是不能遍历而是因为他的遍历机制太耗时间,每次打开一个文件遍历一次这样不妥,所以我们需要在给indexDB数据库添加文件信息时,记录文件信息对应它的存储索引。

文件预览初始

起初,我想的是建一个数组,zip.forEach每执行一次,就往里面添加一个路径信息(即:01借款人申请表资料/实例/申请表与工作证0.jpg),再通过他在数组中的位置来对应记录其在indexDB数据库中的索引,通过indexDB的objectStore.get()直接就可以得到相应信息。但是我们的zip.forEach里面有好几个异步函数,没有人知道它具体何时能执行完,于是,就继续使用对象的方式记录。记录完后,我们需要渲染页面了,对于不同的文件,做成不同的样子,同时,为了优化,我们不能退出了数据库还在,所以在返回时数据库会被删除。

于是,我们把/page/property/upload_review.vue文件最终的代码附上:

<template>
 <div>
   <!-- top -->
   <section class="admin_tool">
     <div class="admin_tool_btn">
       <el-button size="small" @click="gotoBack">
         <i class="fa-chevron-left"></i>
         <span>返回</span>
       </el-button>
     </div>
     <div class="admin_location">
       <el-breadcrumb>
         <el-breadcrumb-item>zip在线预览</el-breadcrumb-item>
       </el-breadcrumb>
     </div>
   </section>
   <section v-if="nonsupport_indexdb">您的浏览器不支持在线预览,请您下载预览</section>
   <section class="file_review" v-else>
     <h3>文件预览</h3>
     <ul class="file_review_list">
       <li v-for="(valuename, keys, index) in file_obj" @click="selectedFile($event)" @dblclick="openfile(valuename, keys)" :title="keys">
         <template v-if="fileTypeNameJudge(keys).file_type === 'photo' && fileTypeNameJudge(keys).file_status === 0">
           <i class="icon_photo"></i>
           <span v-text="keys"></span>
         </template>
         <template v-if="fileTypeNameJudge(keys).file_type === 'excel' && fileTypeNameJudge(keys).file_status === 0">
           <i class="icon_excel"></i>
           <span v-text="keys"></span>
         </template>
         <template v-if="fileTypeNameJudge(keys).error_name === '无法识别此文件' && fileTypeNameJudge(keys).file_status === 0">
           <i class="icon_errorfile"></i>
           <span v-text="keys"></span>
         </template>
         <template v-if="fileTypeNameJudge(keys).file_type === 'dir' && fileTypeNameJudge(keys).file_status === 1">
           <i class="icon_finder"></i>
           <span v-text="keys"></span>
         </template>
       </li>
     </ul>
   </section>
 </div>
</template>
<script>
import JSZip from 'jszip'
export default {
 data () {
   return {
     upload_review_file_name: [], // 文件名存放
     zipfile_index: {},
     file_obj: {},
     nonsupport_indexdb: false,
     imgUrlArr: null
   }
 },
 created () {
   window.onunload = function () { // 关闭页面时设定判断关闭加载为true,同时删除数据库
     window.localStorage.judgeCloseLoadIndexDB = true
     // var indexDB = window.indexedDB
     // indexDB.deleteDatabase('kangruideIndexDB')
   }
   var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB

   if (indexedDB) {
     this.nonsupport_indexdb = false
     if (window.localStorage.judgeCloseLoadIndexDB) {
       this.getBaseData()
     } else {
       var indexDB = window.indexedDB
       var req = indexDB.open('kangruideIndexDB')
       req.onsuccess = () => {
         var curDb = req.result // curDb为数据库对象,用来操作数据表,维护数据表
         var objectStoreNames = JSON.stringify(curDb.objectStoreNames)

         if (objectStoreNames.indexOf('upload_review') !== -1) {
           this.file_obj = JSON.parse(window.localStorage.file_obj)
           this.zipfile_index = JSON.parse(window.localStorage.zipfile_index) // 存储文件在数组中的索引对象
         } else {
           this.getBaseData()
         }
       }
     }
   } else {
     this.$confirm('浏览器不支持在线预览,请进行下载预览', '提示', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning'
     }).then(() => {
       this.nonsupport_indexdb = true
       this.$router.push('/asset/upload_review')
     }).catch(() => {
       this.$alert('取消提交', '提示', {type: 'success'})
     })
   }
 },
 methods: {
   gotoBack () { // 推出到列表则删除数据库
     var indexDB = window.indexedDB
     indexDB.deleteDatabase('kangruideIndexDB')
     window.localStorage.removeItem('file_obj')
     window.localStorage.removeItem('zipfile_index')
     this.$router.go(-1)
   },
   selectedFile (el) {
     let li = document.getElementsByClassName('file_review_list')[0].children
     for (let i = 0, liL = li.length; i < liL; i++) {
       li[i].className = ''
     }
     el.currentTarget.className = 'on'
   },
   openfile (value, keys) {
     window.localStorage.file_obj = JSON.stringify(this.file_obj) // 存储文件对象树

     window.localStorage.curFileObjBranch = JSON.stringify(value) // 存储当前文件对象分支

     if (!window.localStorage.curFileHierarchy) { // 在localStorage中存储对象在文件对象树上的层级-即当前目录层级
       window.localStorage.curFileBranchHierarchy = 0 // 默认0层
     }
     var curfileIndexDbIndexObj = {} // 存放双击的文件在indexDB中的索引信息对象

     window.localStorage.curFileBranchHierarchy = 1 // 在localStorage中存储对象在文件对象树上的层级-即当前目录层级
     window.localStorage.curFileBranchPath = keys // 在localStorage中存储对象在文件对象树上的层级-即当前目录路径

     if (this.$task.getType(value) === 'obj') { // 判断是不是对象,是对象则为文件夹
       // 如果为文件夹则存入其对象分支,当前对象在文件对象树上的层级,并跳转至文件列表页面

       window.localStorage.zipfile_index = JSON.stringify(this.zipfile_index) // 存储文件在数组中的索引对象
       this.$router.push('/property/uploadreviewdetails')
     } else { // 不是对象则为文件
       // 如果为文件则存入其信息,跳转文件处理页面
       curfileIndexDbIndexObj = {index: this.zipfile_index[keys], filename: keys}
       // 把文件索引信息存入localStorage
       window.localStorage.curfileIndexDbIndexObj = JSON.stringify(curfileIndexDbIndexObj)
       this.$router.push('/property/uploadreviewfile')
     }
     // console.log(window.localStorage.curFileHierarchy)
   },
   fileTypeNameJudge (fileName) {
     if (fileName.indexOf('.') !== -1) {
       var sliptFileNameArr = fileName.split('.')
       if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpg' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'png' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpeg' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'gif'
       ) {
         return { file_status: 0, file_type: 'photo' }
       } else if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xls' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsx' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsm' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltx' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltm' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlt'
       ) {
         return { file_status: 0, file_type: 'excel' }
       } else {
         return { file_status: 0, error_name: '无法识别此文件' }
       }
     } else {
       return { file_status: 1, file_type: 'dir' }
       // return { file_status: 1, error_name: '读取错误' }
     }
   },
   handleFileName (filename) {
     var returnObj = {}
     var str = ''
     var parentMax = null
     var curParent = null
     // 文件名的处理
     if (filename.indexOf('/') !== -1) {
       var fileNameArr = filename.split('/')
       for (var i = 0; i < fileNameArr.length; i++) {
         if (i === 0) {
           returnObj[fileNameArr[0]] = {}
           parentMax = fileNameArr[0]
         } else {
           if (i === 1) {
             if (this.fileTypeNameJudge(fileNameArr[1]).file_status === 0) {
               returnObj[fileNameArr[0]][fileNameArr[1]] = fileNameArr[1]
             } else {
               returnObj[fileNameArr[0]][fileNameArr[1]] = {}
               curParent = fileNameArr[1]
               str = fileNameArr[1]
             }
           } else {
             str = str + '/' + fileNameArr[i]
           }
         }
       }
     } else {
       // 如果没有'/'则是文件,不是文件夹
       returnObj[filename] = filename
     }
     var firstafter = {}
     if (str !== '') {
       firstafter = this.handleFileName(str)
     }
     if (curParent !== null) {
       returnObj[parentMax] = firstafter
       // console.log(returnObj[parentMax])
     }
     return returnObj
   },
   getBaseData () {
     var Zip = new JSZip()
     console.log(Zip)
     var self = this
     var url = '/static/lookview.zip'
     var xmlhttp = null
     if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
       /* eslint-disable no-new */
       xmlhttp = new window.XMLHttpRequest()
     } else { // code for IE6, IE5
       /* eslint-disable no-new */
       xmlhttp = new window.ActiveXObject('Microsoft.XMLHTTP')
     }
     xmlhttp.open('GET', url, true)
     xmlhttp.withCredentials = true

     // recent browsers
     if ('responseType' in xmlhttp) {
       xmlhttp.responseType = 'arraybuffer'
     }

     // older browser
     if (xmlhttp.overrideMimeType) {
       xmlhttp.overrideMimeType('text/plain; charset=x-user-defined')
     }
     xmlhttp.send()
     xmlhttp.onreadystatechange = function () {
       if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
         var file = xmlhttp.response || xmlhttp.responseText
         console.log(file)
         JSZip.loadAsync(file).then(function (zip) {
           console.log(zip)
           zip.forEach(function (relativePath, zipEntry) {
             var fileName = zipEntry.name
             // console.log(zipEntry.name)
             if (zipEntry.name.slice(zipEntry.name.length - 1) !== '/') {
               // console.log(zip.folder(zipEntry.name))
               zip.file(zipEntry.name).async('base64').then(function success (text) {
                 var indexDB = window.indexedDB
                 var curDb = null
                 var req = indexDB.open('kangruideIndexDB', 3)
                 req.onupgradeneeded = function () {
                   // 创建表的结构
                   var db = req.result
                   db.createObjectStore('upload_review', {
                     autoIncrement: 'file_id' // 指明当前数据id自增长(indexdb)
                   })
                 }

                 req.onsuccess = function () {
                   // 在成功后对象的result属性为本次申请的结果
                   curDb = req.result // curDb为数据库对象,用来操作数据表,维护数据表
                   var tran = curDb.transaction(['upload_review'], 'readwrite')
                   var objectStore = tran.objectStore('upload_review')
                   // console.log(objectStore)
                   var zipFile = {
                     file_name: fileName,
                     file_content: text
                   }
                   var adduser = objectStore.add(zipFile) // 为当前数据表增加记录
                   adduser.onsuccess = function () {
                     self.zipfile_index[fileName] = adduser.result

                     self.upload_review_file_name.push(fileName)
                     var fileObj = JSON.parse(JSON.stringify(self.file_obj))
                     var fileReturnObj = self.handleFileName(fileName)
                     for (var i in fileReturnObj) {
                       // 先判断这层目录存在与否,如存在则添加,不存在则创建
                       if (fileObj[i]) {
                         fileObj[i] = Object.assign(fileObj[i], fileReturnObj[i])
                       } else {
                         fileObj[i] = fileReturnObj[i]
                       }
                     }
                     self.file_obj = JSON.parse(JSON.stringify(fileObj))
                   }
                 }
               }, function error (e) {
               })
             }
           })
         })
       }
     }
   }
 }
}
</script>

代码说明:我们通过self.zipfile_index[fileName] = adduser.result来记录路径信息在indexDB数据库中的索引,由于我们的文件对象树和文件在数组中的索引对象需要跨页面显示,于是用上了另一个本地存储localStorage,这里详细说说,openfile这个方法:
当我们双击某一个文件夹或文件时,我们把这个文件的分支对象树传递下去,下面依照这个来进行显示,同时我们进入一个目录时,还需记录当前目录的层级,以及它的目录路径,如果在我们的文件对象树上你双击的是一个文件,我们在upload_review_file文件中进行相应的文件处理,如果你双击的是一个文件夹,则在upload_review_details文件中进行文件夹的处理,不同的是,点击文件夹的时候我们需要存储文件在数组中的索引对象,点击文件时,我们要把文件信息进行处理,使用window.localStorage.curfileIndexDbIndexObj,把文件索引信息存入localStorage,在upload_review_file文件需要的时候进行调用。
到了这里大家明白在upload_review_file文件中我们处理任何的文件信息,在upload_review_file文件中我们处理任何包含目录的信息,在upload_review文件中则是我们的顶目录。

我们把/page/property/upload_review_file.vue文件最终的代码附上:

<template>
 <div>
   <!-- top -->
   <section class="admin_tool">
     <div class="admin_tool_btn">
       <el-button size="small" @click="gotoBack">
         <i class="fa-chevron-left"></i>
         <span>返回</span>
       </el-button>
     </div>
     <div class="admin_location">
       <el-breadcrumb>
         <el-breadcrumb-item>zip在线预览-文件查看</el-breadcrumb-item>
       </el-breadcrumb>
     </div>
   </section>
   <section class="file_review">
     <h3>文件预览</h3>
     <span class="file_breadcrumb" v-text="this.curfile_infor.file_name"></span>
     <div class="review_box" v-if="this.curfile_infor.file_name">
       <template v-if="fileTypeNameJudge(this.curfile_infor.file_name).file_type === 'photo' && fileTypeNameJudge(this.curfile_infor.file_name).file_status === 0">
         ![]('data:image/jpeg;base64,' + this.curfile_infor.file_content)
       </template>
       <div class="excel_review" v-if="fileTypeNameJudge(this.curfile_infor.file_name).file_type === 'excel' && fileTypeNameJudge(this.curfile_infor.file_name).file_status === 0">
         <!-- 通过a标签download属性,配合href连接('data:application/vnd.ms-excel;base64,' + base64编码)解码来实现文件下载 -->
         <i class="icon_excel"></i>
         <em v-text="this.curfile_infor.file_name"></em>
         <a :download="this.curfile_infor.file_name" :href="requestfileinfor" @click="downloadExcel(curfile_infor.file_content)">
           <el-button type="primary" size="mini">下载表格</el-button>
         </a>
       </div>
       <span v-if="fileTypeNameJudge(this.curfile_infor.file_name).error_name === '无法识别此文件' && fileTypeNameJudge(this.curfile_infor.file_name).file_status === 0">
         <i class="fa-exclamation-circle fa-2x file-icon"></i>
         {{'无法识别此文件'}}
       </span>
       <span v-if="fileTypeNameJudge(this.curfile_infor.file_name).file_type === 'dir' && fileTypeNameJudge(this.curfile_infor.file_name).file_status === 1">
         <i class="fa-file fa-2x file-icon"></i>
         <span v-text="value.filename"></span>
       </span>
     </div>
   </section>
 </div>
</template>
<script>
export default {
 data () {
   return {
     requestfileinfor: null,
     curlocal_infor: {},
     curfile_infor: {}
   }
 },
 created () {
   this.getBaseData()
 },
 methods: {
   gotoBack () {
     window.localStorage.curFileBranchHierarchy-- // 减层级
     var curFileBranchPath = window.localStorage.curFileBranchPath
     var fileObj = JSON.parse(window.localStorage.file_obj)
     if (curFileBranchPath.indexOf('/') !== -1) { // 判断有无/,如果无则是最顶级,清空所有与目录相关的
       var pathArray = curFileBranchPath.split('/') // 减当前目录路径
       var curFilePath = ''
       var curFileObjBranch = {} // 获取当前文件父级对象分支

       for (var i = 0; i < pathArray.slice(0, pathArray.length - 1).length; i++) {
         if (curFilePath === '') {
           curFilePath = pathArray.slice(0, pathArray.length - 1)[i]
         } else {
           curFilePath = curFilePath + '/' + pathArray.slice(0, pathArray.length - 1)[i]
         }

         if (!this.$task.judgeIsNullObj(curFileObjBranch)) { // 初始时直接file_obj赋值
           curFileObjBranch = fileObj[pathArray.slice(0, pathArray.length - 1)[0]]
         } else {
           // 不是初始值在curFileObjBranch中取
           curFileObjBranch = curFileObjBranch[pathArray.slice(0, pathArray.length - 1)[i]]
         }
       }
       window.localStorage.curFileBranchPath = curFilePath

       window.localStorage.curFileObjBranch = JSON.stringify(curFileObjBranch)
     } else {
       window.localStorage.removeItem('curfileIndexDbIndexObj')
       window.localStorage.removeItem('curFileObjBranch')
       window.localStorage.removeItem('curFileBranchPath')
       window.localStorage.removeItem('curFileBranchHierarchy')
     }
     this.$router.go(-1)
   },
   downloadExcel (filecontent) {
     this.requestfileinfor = 'data:application/vnd.ms-excel;base64,' + filecontent
   },
   fileTypeNameJudge (fileName) {
     if (fileName.indexOf('.') !== -1) {
       var sliptFileNameArr = fileName.split('.')
       if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpg' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'png' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpeg' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'gif'
       ) {
         return { file_status: 0, file_type: 'photo' }
       } else if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xls' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsx' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsm' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltx' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltm' ||
           sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlt'
       ) {
         return { file_status: 0, file_type: 'excel' }
       } else {
         return { file_status: 0, error_name: '无法识别此文件' }
       }
     } else {
       return { file_status: 1, file_type: 'dir' }
     }
   },
   getBaseData () {
     var self = this
     var curfileInfo = window.localStorage.curfileIndexDbIndexObj
     this.curlocal_infor = JSON.parse(curfileInfo)
     var indexDB = window.indexedDB

     var curDb = null
     var requestKeys = this.curlocal_infor.index
     var req = indexDB.open('kangruideIndexDB')
     req.onsuccess = function () {
       curDb = req.result // curDb为数据库对象,用来操作数据表,维护数据表
       var tran = curDb.transaction(['upload_review'], 'readwrite')
       var objectStore = tran.objectStore('upload_review')
       console.log(objectStore)
       var getopenfile = objectStore.get(requestKeys)
       getopenfile.onsuccess = function () {
         console.log(getopenfile.result)
         self.curfile_infor = getopenfile.result
       }
     }
   }
 }
}
</script>

代码说明:我们获取到window.localStorage.curfileIndexDbIndexObj传递过来的索引,然后通过indexDB特有的方式进行访问,我们取到了结果,如图:


这里由于网页不支持excel,所以我们赋予下载功能本地去打开,通过a标签的新属性download来下载:

<a :download="this.curfile_infor.file_name" :href="requestfileinfor" @click="downloadExcel(curfile_infor.file_content)">
    <el-button type="primary" size="mini">下载表格</el-button>
</a>

由于我们使用base64编码方式存储的二进制信息,所以得把二进制信息转换为文件信息:

downloadExcel (filecontent) {
     this.requestfileinfor = 'data:application/vnd.ms-excel;base64,' + filecontent
}

data:application/vnd.ms-excel;base64,是一种二进制变为文件的方式。
我们需要返回到上一级目录,所以我们保存的当前目录的分支及层级就拍上用场:

gotoBack () {
      window.localStorage.curFileBranchHierarchy-- // 减层级
      var curFileBranchPath = window.localStorage.curFileBranchPath
      var fileObj = JSON.parse(window.localStorage.file_obj)
      if (curFileBranchPath.indexOf('/') !== -1) { // 判断有无/,如果无则是最顶级,清空所有与目录相关的
        var pathArray = curFileBranchPath.split('/') // 减当前目录路径
        var curFilePath = ''
        var curFileObjBranch = {} // 获取当前文件父级对象分支
        for (var i = 0; i < pathArray.slice(0, pathArray.length - 1).length; i++) {
          if (curFilePath === '') {
            curFilePath = pathArray.slice(0, pathArray.length - 1)[i]
          } else {
            curFilePath = curFilePath + '/' + pathArray.slice(0, pathArray.length - 1)[i]
          }
          if (!this.$task.judgeIsNullObj(curFileObjBranch)) { // 初始时直接file_obj赋值
            curFileObjBranch = fileObj[pathArray.slice(0, pathArray.length - 1)[0]]
          } else {
            // 不是初始值在curFileObjBranch中取
            curFileObjBranch = curFileObjBranch[pathArray.slice(0, pathArray.length - 1)[i]]
          }
        }
        window.localStorage.curFileBranchPath = curFilePath
        window.localStorage.curFileObjBranch = JSON.stringify(curFileObjBranch)
      } else {
        window.localStorage.removeItem('curfileIndexDbIndexObj')
        window.localStorage.removeItem('curFileObjBranch')
        window.localStorage.removeItem('curFileBranchPath')
        window.localStorage.removeItem('curFileBranchHierarchy')
      }
      this.$router.go(-1)
}

我们也把/page/property/upload_review_details.vue文件最终的代码附上:

<template>
  <div>
    <!-- top -->
    <section class="admin_tool">
      <div class="admin_tool_btn">
        <el-button size="small" @click="gotoBack">
          <i class="fa-chevron-left"></i>
          <span>返回</span>
        </el-button>
      </div>
      <div class="admin_location">
        <el-breadcrumb>
          <el-breadcrumb-item>zip在线预览</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
    </section>
    <section class="file_review">
      <h3>文件预览</h3>
      <span class="file_breadcrumb" v-text="breadcrumb"></span>
      <ul class="file_review_list">
        <li class="file_list_other" v-for="(value, keys, index) in curFileObjBranch" @click="selectedFile($event)" @dblclick="openfile(value, keys)">
          <template v-if="fileTypeNameJudge(keys).file_type === 'photo' && fileTypeNameJudge(keys).file_status === 0">
            <i class="icon_photo"></i>
            <span v-text="keys"></span>
          </template>
          <template v-if="fileTypeNameJudge(keys).file_type === 'excel' && fileTypeNameJudge(keys).file_status === 0">
            <i class="icon_excel"></i>
            <span v-text="keys"></span>
          </template>
          <template v-if="fileTypeNameJudge(keys).error_name === '无法识别此文件' && fileTypeNameJudge(keys).file_status === 0">
            <i class="icon_errorfile"></i>
            <span v-text="keys"></span>
          </template>
          <template v-if="fileTypeNameJudge(keys).file_type === 'dir' && fileTypeNameJudge(keys).file_status === 1">
            <i class="icon_finder"></i>
            <span v-text="keys"></span>
          </template>
        </li>
      </ul>
    </section>
  </div>
</template>
<script>
export default {
  data () {
    return {
      file_obj: {},
      zipfile_index: {},
      curFileObjBranch: [],
      imgUrlArr: null,
      breadcrumb: this.$store.get('curFileBranchPath')
    }
  },
  created () {
    this.getBaseData()
  },
  methods: {
    gotoBack () {
      window.localStorage.curFileBranchHierarchy-- // 减层级
      var curFileBranchPath = window.localStorage.curFileBranchPath
      var fileObj = JSON.parse(window.localStorage.file_obj)
      if (curFileBranchPath.indexOf('/') !== -1) { // 判断有无/,如果无则是最顶级,清空所有与目录相关的
        var pathArray = curFileBranchPath.split('/') // 减当前目录路径
        var curFilePath = ''
        var curFileObjBranch = {} // 获取当前文件父级对象分支

        for (var i = 0; i < pathArray.slice(0, pathArray.length - 1).length; i++) {
          if (curFilePath === '') {
            curFilePath = pathArray.slice(0, pathArray.length - 1)[i]
          } else {
            curFilePath = curFilePath + '/' + pathArray.slice(0, pathArray.length - 1)[i]
          }

          if (!this.$task.judgeIsNullObj(curFileObjBranch)) { // 初始时直接file_obj赋值
            curFileObjBranch = fileObj[pathArray.slice(0, pathArray.length - 1)[0]]
          } else {
            // 不是初始值在curFileObjBranch中取
            curFileObjBranch = curFileObjBranch[pathArray.slice(0, pathArray.length - 1)[i]]
          }
        }
        window.localStorage.curFileBranchPath = curFilePath

        window.localStorage.curFileObjBranch = JSON.stringify(curFileObjBranch)
        this.$router.push('/property/uploadreviewdetails')
        this.getBaseData()
      } else {
        window.localStorage.removeItem('curfileIndexDbIndexObj')
        window.localStorage.removeItem('curFileObjBranch')
        window.localStorage.removeItem('curFileBranchPath')
        window.localStorage.removeItem('curFileBranchHierarchy')
        this.$router.go(-1)
      }
    },
    selectedFile (el) {
      let li = document.getElementsByClassName('file_review_list')[0].children
      for (let i = 0, liL = li.length; i < liL; i++) {
        li[i].className = ''
      }
      el.currentTarget.className = 'on'
    },
    openfile (value, keys) {
      window.localStorage.curFileObjBranch = JSON.stringify(value) // 存储当前文件对象分支
      window.localStorage.curFileBranchHierarchy++ // 加层级-即当前目录层级
      var parentPath = window.localStorage.curFileBranchPath // 获取父级路径
      window.localStorage.curFileBranchPath = parentPath + '/' + keys // 当前目录路径
      var curfileIndexDbIndexObj = {} // 存放双击的文件在indexDB中的索引信息对象
      if (this.$task.getType(value) === 'obj') { // 判断是不是对象,是对象则为文件夹
        // 如果为文件夹则存入其对象分支,当前对象在文件对象树上的层级,并跳转至文件列表页面

        window.localStorage.zipfile_index = JSON.stringify(this.zipfile_index) // 存储文件在数组中的索引对象
        this.$router.push('/property/uploadreviewdetails')
        this.getBaseData()
      } else { // 不是对象则为文件
        // 如果为文件则存入其信息,跳转文件处理页面
        curfileIndexDbIndexObj = {index: this.zipfile_index[parentPath + '/' + keys], filename: keys}
        // 把文件索引信息存入localStorage
        window.localStorage.curfileIndexDbIndexObj = JSON.stringify(curfileIndexDbIndexObj)
        this.$router.push('/property/uploadreviewfile')
      }
    },
    fileTypeNameJudge (fileName) {
      if (fileName.indexOf('.') !== -1) {
        var sliptFileNameArr = fileName.split('.')
        if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpg' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'png' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'jpeg' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'gif'
        ) {
          return { file_status: 0, file_type: 'photo' }
        } else if (sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xls' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsx' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlsm' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltx' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xltm' ||
            sliptFileNameArr[sliptFileNameArr.length - 1].toLowerCase() === 'xlt'
        ) {
          return { file_status: 0, file_type: 'excel' }
        } else {
          return { file_status: 0, error_name: '无法识别此文件' }
        }
      } else {
        return { file_status: 1, file_type: 'dir' }
        // return { file_status: 1, error_name: '读取错误' }
      }
    },
    getBaseData () {
      this.zipfile_index = JSON.parse(window.localStorage.zipfile_index) // 存储文件在数组中的索引对象
      this.curFileObjBranch = JSON.parse(window.localStorage.curFileObjBranch) // 获取当前文件对象分支
    }
  }
}
</script>

代码说明: 先获取文件在数组中的索引对象及当前文件对象分支,然后渲染,双击文件时跟上面的类似,就是在返回上一级的时候麻烦些,得从文件对象树里面找到当前分支的位置,然后把当前分支的父级找到,再父级分支变为当前分支,减去目录层级以及相关信息的存储。

到了这里实战就结束了,完整的样子展示如图:




小结:

至此这个项目实战就结束了,总计奋战了好几天,这里想办法在github上把项目:VUEIndexDBOnlineZIP分享给大家,祝大家学习愉快。

提示:在最近几天我会慢慢附上VUE系列教程的其他后续篇幅,后面还有精彩敬请期待,请大家关注我的专题:web前端。如有意见可以进行评论,每一条评论我都会认真对待。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容