Просмотр исходного кода

feat: 1.1.0版的图片预览组件

任一存 4 лет назад
Родитель
Сommit
21caa8061f

BIN
src/assets/images/icons/material_preview_close@2x.png


+ 5 - 11
src/views/material/image/index.vue

@@ -59,7 +59,7 @@
           {{ data.name }}
         </div>
         <div slot-scope="{ data, item, sub }" slot="item" style="width: 100%">
-          <div class="handle" v-if="sub.canclick">
+          <div v-if="sub.canclick" class="handle">
             <i
               class="iconfont iconbs_list_edit hover-tips"
               @click="(showRename = true), (popupItem = item)"
@@ -74,17 +74,15 @@
               </div>
             </i>
           </div>
-          <div class="img" v-else-if="sub.type == 'image'">
+          <div v-else-if="sub.type == 'image'" class="img">
             <img
               :id="'img' + item.id"
-              v-viewer
               :src="data + `?${Math.random()}`"
               alt=""
             />
           </div>
           <span
             v-else
-            @click="sub.fontweight && viewImg('img' + item.id)"
             :style="{ fontWeight: sub.fontweight, color: '#202020' }"
             >{{ data || "-" }}</span
           >
@@ -109,11 +107,7 @@
       @rename="handleRename"
       @close="showRename = false"
     />
-    <preview
-      :item="popupItem"
-      :show="showPreview"
-      @close="showPreview = false"
-    />
+    <preview/>
   </div>
 </template>
 
@@ -126,7 +120,7 @@ import rename from "../popup/rename";
 import UploadTaskList from "../components/uploadList1.1.0.vue";
 import Upload from "@/components/shared/uploads/UploadMultiple";
 import { changeByteUnit } from "@/utils/file";
-import preview from "../popup/preview";
+import preview from "../popup/preview1.1.0";
 import { debounce } from "@/utils/other.js"
 import { mapState } from 'vuex';
 
@@ -150,7 +144,7 @@ export default {
   },
   data() {
     return {
-      config,
+      config, // TODO: 没必要这么弄
       showPreview: false,
       showRename: false,
       showList: false,

+ 233 - 0
src/views/material/popup/preview1.1.0.vue

@@ -0,0 +1,233 @@
+<template>
+  <popup v-if="ifShow">
+    <div class="preview-wrapper">
+      <div class="title">{{imageTitleList[currentIndex]}}</div>
+      <img class="close-btn" :src="require('@/assets/images/icons/material_preview_close@2x.png')" @click=onClickClose />
+      <img
+        class="image"
+        :src="imageList[currentIndex]"
+        :style="imageStyle"
+        @wheel.prevent="onImageWheel"
+      />
+      <div class="toolbar">
+        <i
+          class="iconfont icon-material_preview_previous hover-tips" @click="onClickPrevious()">
+          <div>
+            <div class="remark">上一张</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next1 hover-tips append-splitter" @click="onClickNext()">
+          <div>
+            <div class="remark">下一张</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_enlarge hover-tips" @click="onClickZoomIn()">
+          <div>
+            <div class="remark">放大</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_narrow hover-tips" @click="onClickZoomOut()">
+          <div>
+            <div class="remark">缩小</div>
+          </div>
+        </i>
+        <i class="iconfont icon-material_preview_next hover-tips-warn" @click="onClickDelete()">
+          <div>
+            <div class="remark">删除</div>
+          </div>
+        </i>
+        <i v-if="objectFit === 'scale-down'" class="iconfont icon-material_preview_full_screen hover-tips" @click="onClickFullScreen()">
+          <div>
+            <div class="remark">全屏</div>
+          </div>
+        </i>
+        <i v-if="objectFit === 'contain'" class="iconfont icon-material_preview_drop_out hover-tips" @click="onClickCancelFullScreen()">
+          <div>
+            <div class="remark">取消全屏</div>
+          </div>
+        </i>
+      </div>
+    </div>
+  </popup>
+</template>
+
+<script>
+import Popup from "@/components/shared/popup";
+
+export default {
+  props: {
+    ifShow: {
+      type: Boolean,
+      default: true
+    },
+    imageTitleList: {
+      type: Array,
+      default: () => {
+        return [
+          'aaa',
+          'bbb'
+        ]
+      }
+    },
+    imageList: {
+      type: Array,
+      default: () => {
+        return [
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_114634855.jpg',
+          'https://oss-xiaoan.oss-cn-shenzhen.aliyuncs.com/720yun_fd_manage/fodder/20220125_142545584.jpg',
+        ]
+      }
+    },
+    canScale: {
+      type: Boolean,
+      default: true
+    },
+    canFullScreen: {
+      type: Boolean,
+      default: true
+    },
+  },
+  components:{
+    Popup
+  },
+  data(){
+    return {
+      currentIndex: 0,
+      scaleRate: 1,
+      objectFit: 'scale-down',
+    }
+  },
+  computed: {
+    imageStyle() {
+      return {
+        transform: `scale(${this.scaleRate})`,
+        objectFit: this.objectFit,
+      }
+    }
+  },
+  watch: {
+    imageList: {
+      handler: function (newList) {
+        if (newList.length - 1 < this.currentIndex) {
+          this.currentIndex = newList.length - 1
+        }
+      }
+    }
+  },
+  methods:{
+    onImageWheel(e) {
+      if (e.deltaY > 0) {
+        this.scaleRate = this.scaleRate * 1.1
+      } else {
+        this.scaleRate = this.scaleRate * 0.9
+      }
+    },
+    onClickPrevious() {
+      if (this.currentIndex > 0) {
+        this.currentIndex--
+      }
+    },
+    onClickNext() {
+      if (this.currentIndex < this.imageList.length - 1) {
+        this.currentIndex++
+      }
+    },
+    onClickZoomIn() {
+      this.scaleRate = this.scaleRate * 1.1
+    },
+    onClickZoomOut() {
+      this.scaleRate *= 0.9
+    },
+    onClickDelete(item) {
+      this.$emit('click-delete', item)
+    },
+    onClickFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'contain'
+    },
+    onClickCancelFullScreen() {
+      this.scaleRate = 1
+      this.objectFit = 'scale-down'
+    },
+    onClickClose() {
+      this.$emit('click-close')
+    }
+  }
+}
+</script>
+
+<style scoped lang="less">
+  .preview-wrapper {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    .title {
+      position: absolute;
+      top: 16px;
+      left: 30px;
+      z-index: 2;
+      height: 36px;
+      font-size: 14px;
+      color: #FFFFFF;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 18px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding-left: 16px;
+      padding-right: 16px;
+    }
+    .close-btn {
+      position: absolute;
+      top: 16px;
+      right: 30px;
+      width: 36px;
+      height: 36px;
+      z-index: 2;
+      cursor: pointer;
+    }
+    .toolbar {
+      position: absolute;
+      bottom: 147px;
+      left: 50%;
+      transform: translateX(-50%);
+      height: 60px;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      padding: 0 43px;
+      background: rgba(0, 0, 0, 0.6);
+      border-radius: 8px;
+      z-index: 2;
+      .iconfont {
+        cursor: pointer;
+        color: white;
+        margin-right: 36px;
+        font-size: 22px;
+        &:last-child {
+          margin-right: 0;
+        }
+      }
+      .append-splitter {
+        &::after {
+          content: "|";
+          position: absolute;
+          right: -18px;
+          top: -4px;
+          font-size: 20px;
+          color: rgba(255, 255, 255, 0.5);
+        }
+      }
+    }
+    .image {
+      top: 0;
+      left: 0;
+      width: 100%;
+      height: 100%;
+      position: absolute;
+      z-index: 1;
+    }
+  }
+</style>