vue - 放大镜组件

最近在整理之前的代码,所以将 放大镜以组建的形式整理了一下,如果你的组件中的图片数据是通过接口获取,你可以在组件的 mounted钩子函数中调用接口

<template>
  <div class="magnifier-container">
    <div class="magnifier-mian" @mousemove="glassMoveHandle" @mouseleave="glassLeaveHandle">
      <img ref="orginImg" :src="src" alt="">
      <div ref="magnifierCover" class="magnifier-cover"></div>
    </div>
    <ul class="magnifier-img-list" @mousemove="imgMoveHandle">
      <li v-for="item in srcs" :key="item.src" :src="item.src" :class="{'active':item.src === src}">
        <img :src="item.src" alt="" :data-src="item.src" />
      </li>
    </ul>
    <div ref="magnifierBig" class="magnifier-big"></div>
  </div>
</template>

<script>
export default {
  name:"magnifier",
  props: {
      coversrc:{
        type:String,
        default:'/images/image1.jpg'             // 放大镜遮罩图片
      },
      srcs:{                                     // 需要发大的图片的路径 和大图路径
        type:Array,
        default:() => [{
          src:"/images/image1.jpg",
          bigsrc:"/images/bigimage1.jpg"
        },{
          src:"/images/image2.jpg",
          bigsrc:"/images/bigimage2.jpg"
        },{
          src:"/images/image3.jpg",
          bigsrc:"/images/bigimage3.jpg"
        },{
          src:"/images/image4.jpg",
          bigsrc:"/images/bigimage4.jpg"
        }]
      }
  },
  data(){
    return {                                       
      src:''                                    // 当前选中第一张图片
    }
  },
  mounted(){
    this.src = this.srcs[0].src;               //  默认选中第一张图片
    this.$nextTick(()=>{  
      this.$refs.magnifierCover.style.backgroundImage = `url(${this.coversrc})`;   // 设置遮罩图片
      thi    s.$refs.magnifierBig.style.backgroundImage = `url(${this.srcs[0].src})`;  //设置大图
    });
  },
  methods:{
    /* 鼠标移入事件 */
    imgMoveHandle:function(event){
      let { src } = event.target.dataset;
      if(src){
        let srcObj = this.srcs.find(c=>c.src === src);
        if(srcObj){
          this.src = srcObj.src;
          this.$refs.magnifierBig.style.backgroundImage = `url(${srcObj.bigsrc})`;
        }
      }
    },
    /** 放大镜移入 **/
    glassMoveHandle:function(event){
      // 鼠标的位置
      let x = event.clientX, y = event.clientY;  
      // 获取元素
      let imgEl = this.$refs.orginImg.getBoundingClientRect();
      // 获取元素左上角的坐标
      let cx = imgEl.left,cy = imgEl.top;
      let coverEl = this.$refs.magnifierCover.getBoundingClientRect();
      let tx = x - cx - coverEl.width/2;
      let ty = y - cy - coverEl.height/2;
      let maxX = imgEl.width - coverEl.width;
      if(tx < 0)
        tx = 0;
      else{
        tx = tx > maxX ? maxX : tx;
      }
      let maxY = imgEl.height - coverEl.height;
      if(ty < 0)
        ty = 0
      else{
        ty = ty > maxY ? maxY:ty;
      } 
      this.$refs.magnifierCover.style.display = 'block';
      this.$refs.magnifierBig.style.display = 'block';
      this.$refs.magnifierBig.style.backgroundPosition = `${ tx / maxX * 100 }% ${ ty / maxY * 100 }%`;
      this.$refs.magnifierCover.style.left = `${tx}px`; 
      this.$refs.magnifierCover.style.top = `${ty}px`;
    },
    /***移出事件*/
    glassLeaveHandle:function(){
      this.$refs.magnifierCover.style.display = 'none';
      this.$refs.magnifierBig.style.display = 'none';
    }
  }
}
</script>

<style lang="less" scoped>
.magnifier-container{
  width: 400px;
  border: 1px solid #000;
  position: relative;
  .magnifier-mian{
    position: relative;
    width: 400px;
    height: 400px;
    margin-bottom: 15px;
    img{
      display: block;
      width: 100%;
      height: 100%;
    }
    .magnifier-cover{
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      width: 120px;
      height: 120px;
      border: 1px solid red;
    }
  }
  .magnifier-big{
    position:absolute;
    display: none;
    top: 0;
    left: 400px;
    width: 400px;
    height: 400px;
    border: 1px solid #000;
    background-size: 287%;
  }
  ul {
    margin: 0;
    padding: 0;
    margin-bottom: 15px;
    list-style: none;
    display: flex;
    justify-content: left;
    li {
      margin-left: 10px;
      img{
        display: block;
        width: 50px;
        height: 50px;
      }
    }
    li.active{
      border:2px solid red;
    }
  }
}
</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值