双击放大预览功能/组件


imgPreview组件

<template>
  <div class="vue-uploader" @keyup.esc.native="hide">
    <div v-if="visible" @click.self="hide" class="img_model" >
      <div class="img-btn btn-pre" @click="preImg" v-show="imgList.length>1"><i class="el-icon-arrow-left"></i></div>
      <div class="img-btn btn-next" @click="nextImg" v-show="imgList.length>1"><i class="el-icon-arrow-right"></i></div>
      <div class="center-box">
        <div class="img_box" v-bind:style="{ transform: 'rotate(' + deg + 'deg)' }">
          <img :src="imgList[imgIndex]" alt="" id="oImg" @click="e=>e.stopPropagation()"  v-bind:style="{ zoom: zoom }">
        </div>
      </div>
      <div @click="e=>e.stopPropagation()" class="btns">
        <img src="https://static-frontpicture.lexing360.com/min.png" @click="imgToSize(false)">
        <img src="https://static-frontpicture.lexing360.com/rotate.png" @click="rotate">
        <img src="https://static-frontpicture.lexing360.com/plus.png" @click="imgToSize(true)">
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    props: {
      initImgIndex: {
        required: true
      },
      imgList: {
        required: true,
      },
      visible: {
        required: true
      },
    },
    data() {
      return {
        src: '',
        pasteText: '',
        zoom: '100%',
        imgIndex: 0,
        deg: 0,
        firstTag: true
      }
    },
    created () {
      this.imgIndex = this.initImgIndex
    },
    watch: {
      visible(val) {
        this.imgIndex = this.initImgIndex
        this.zoom = '100%'
        this.firstTag = true
        this.$emit('update:visible', val);
        if (val) {
          this.$emit('open');
        } else {
          this.$el.removeEventListener('scroll', this.updatePopper);
          this.$emit('close');
        }
      }
    },
    methods: {
      imgToSize(oBool) {
        if (this.firstTag && !oBool && document.getElementById('oImg') && document.getElementById('oImg').naturalWidth > window.innerWidth) {
          this.zoom = parseInt(window.innerWidth * 0.9 / document.getElementById('oImg').naturalWidth * 100) + '%'
          this.firstTag = false
        }
        if ((document.getElementById('oImg').width * parseInt(this.zoom) / 100 <= 200 || this.zoom == '2%') && !oBool) {
          this.$message.info('已经最小了!')
          return
        }
        if (document.getElementById('oImg') && document.getElementById('oImg').x <= window.innerWidth * 0.05 && oBool) {
          this.$message.info('已经最大了!')
          return
        }
        this.zoom = parseInt(this.zoom) + (oBool ? 2 : -2) + '%';  
      },
      rotate () {
        this.deg += 90
      },
      nextImg (e) {
        e.stopPropagation()
        if (this.imgIndex == this.imgList.length-1) {
          this.imgIndex = 0
        } else {
          this.imgIndex ++
        }

      },
      preImg(e) {
        e.stopPropagation()
        if (this.imgIndex == 0) {
          this.imgIndex = this.imgList.length - 1
        } else {
          this.imgIndex --
        }
      },
      
      hide (cancel) {
        if (cancel !== false) {
          this.$emit('update:visible', false);
          this.$emit('visible-change', false);
        }
      },
    }
  }
</script>
<style>
  .img_model{
    position: fixed;
     100%;
    min-height: 100%;
    background: rgba(0,0,0,.5);
    top: 0;
    left: 0;
    z-index: 9999;
    /* text-align: center; */
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center; 
  }
  .center-box {
    position: relative;
    max- 90%;
  }
  .img_model .img_box {
    max- 100%;
    max-height: 800px;
    overflow-y: scroll;
  }
  .img_model .img_box::-webkit-scrollbar {
    display: none;
}
  .img_model .img_box img{
    max- 100%;
  }
  .img_model .img-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 100;
     50px;
    height: 70px;
    font-size: 30px;
    line-height: 70px;
    text-align: center;
    background: rgba(255, 255, 255, .3);
    color: #FFF;
  }
  .img_model .btn-pre {
    left: 5%;
  }
  .img_model .btn-next {
    right: 5%;
  }
  .img_model .img_box .btn-next {
    right: 20rpx;
  }
  .img_model .btns{
    position: fixed;
    bottom: 25px;
    -webkit-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    user-select:none;
  }
</style>

引入这个组件

  import imgPreview from './imgPreview'
   data:{
     return{
        bigImgShow: false,
        bigImgIndex:'',
        imgList:[],
     }
   }
   components: {
      imgPreview
    },  
    method:{
       previewImage (imgList, index) {
        if (imgList) {
          this.imgList = imgList
          this.bigImgIndex = index
          this.bigImgShow = true
       }
      },
    }

template里面渲染

 <imgPreview :visible.sync="bigImgShow" :initImgIndex="bigImgIndex" :imgList="imgList"></imgPreview>    
原文地址:https://www.cnblogs.com/antyhouse/p/10275747.html