效果:

PicZoom.vue(图片放大组件)

<template><divclass="magnifier-box":class="vertical?'vertical':''":ref="id"@mousemove="mousemove"@mouseover="mouseover"@mouseleave="mouseleave"><img v-show="showImg" :src="imgUrl" alt /><div class="mouse-cover"></div><img :src="bigImage" class="big-image" v-show="showImage" /></div>
</template><script>
export default {props: {scale: {type: Number,default: 2.5},url: {type: String,required: true},bigUrl: {type: String,default: null},scroll: {type: Boolean,default: false},showEidt: {type: Boolean,default: false}},data() {return {bigImage: null,showImage: null,id: null,cover: null,imgbox: null,imgwrap: null,orginUrl: null,bigImgUrl: null,bigOrginUrl: null,imgUrl: null,img: null,canvas: null,ctx: null,rectTimesX: 0,rectTimesY: 0,imgTimesX: 0,imgTimesY: 0,init: false,step: 0,bigStep: 0,vertical: false,showImg: true};},created() {var $chars ="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/var maxPos = $chars.length;var str = "";for (let i = 0; i < 10; i++) {str += $chars.charAt(Math.floor(Math.random() * maxPos));}this.id = str;this.imgUrl = this.url;this.orginUrl = this.url;this.bigImgUrl = this.bigUrl;this.bigOrginUrl = this.bigUrl;},watch: {url: function(val) {this.imgUrl = val;this.orginUrl = val;this.initTime();},bigUrl: function() {this.bigImgUrl = bigUrl;this.bigOrginUrl = bigUrl;this.initTime();}},mounted() {this.$nextTick(() => {this.initTime();});},methods: {initTime() {this.init = false;let box = this.$refs[this.id];this.imgbox = box;this.cover = box.querySelector(".mouse-cover");this.cover.style.width = this.imgbox.offsetWidth / this.scale + "px";this.cover.style.height = this.imgbox.offsetHeight / this.scale + "px";this.cover.style.left = "-100%";this.cover.style.top = "-100%";this.imgwrap = box.querySelector("img");let imgsrc;if (this.bigImgUrl) {imgsrc = this.bigImgUrl;} else {imgsrc = this.imgUrl;}this.img = new Image();this.img.src = imgsrc;this.img.onload = () => {(this.rectTimesX =this.imgbox.offsetWidth / this.scale / this.imgwrap.offsetWidth),(this.rectTimesY =this.imgbox.offsetHeight / this.scale / this.imgwrap.offsetHeight);(this.imgTimesX = this.img.width / this.imgwrap.offsetWidth),(this.imgTimesY = this.img.height / this.imgwrap.offsetHeight);this.vertical = this.img.width < this.img.height;this.init = true;};if (this.canvas) {this.canvas = null;}this.canvas = document.createElement("canvas");this.canvas.className = "mouse-cover-canvas";this.canvas.style.position = "absolute";this.canvas.style.left = this.imgbox.offsetLeft + this.imgbox.offsetWidth + 10 + "px";this.imgbox.offsetLeft + this.imgbox.offsetWidth + 10 + "px";this.canvas.style.top = this.imgbox.offsetTop + "px";this.canvas.style.border = "1px solid #eee";this.canvas.style.zIndex = "99999";this.canvas.height = this.imgbox.offsetHeight;this.canvas.width = this.imgbox.offsetWidth;this.canvas.style.display = "none";// document.body.append(this.canvas);this.ctx = this.canvas.getContext("2d");this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);},initBox() {this.showImg = false;this.canvas.style.display = "none";let box = this.$refs[this.id];let imgsrc;if (this.bigImgUrl) {imgsrc = this.bigImgUrl;} else {imgsrc = this.imgUrl;}this.img = new Image();this.img.src = imgsrc;this.img.onload = () => {this.vertical = this.img.width < this.img.height;this.showImg = true;let thumb = box.querySelector("img");setTimeout(() => {(this.rectTimesX =this.imgbox.offsetWidth /this.scale /box.querySelector("img").offsetWidth),(this.rectTimesY =this.imgbox.offsetHeight /this.scale /box.querySelector("img").offsetHeight);}, 20);};},mousemove(e) {if (!this.init) {return false;}let _this = this;//获取实际的offsetfunction offset(curEle) {var totalLeft = null,totalTop = null,par = curEle.offsetParent;//首先加自己本身的左偏移和上偏移totalLeft += curEle.offsetLeft;totalTop += curEle.offsetTop;//只要没有找到body,我们就把父级参照物的边框和偏移也进行累加while (par) {if (navigator.userAgent.indexOf("MSIE 8.0") === -1) {//累加父级参照物的边框totalLeft += par.clientLeft;totalTop += par.clientTop;}//累加父级参照物本身的偏移totalLeft += par.offsetLeft;totalTop += par.offsetTop;par = par.offsetParent;}return {left: totalLeft,top: totalTop};}function getXY(eve) {return {x: eve.clientX - _this.cover.offsetWidth / 2,y: eve.clientY - _this.cover.offsetHeight / 2};}let oEvent = e || event;let pos = getXY(oEvent);let imgwrap = offset(this.imgwrap);let range = {minX: imgwrap.left,maxX: imgwrap.left + this.imgwrap.offsetWidth - this.cover.offsetWidth,minY: imgwrap.top - document.documentElement.scrollTop,maxY:imgwrap.top -document.documentElement.scrollTop +this.imgwrap.offsetHeight -this.cover.offsetHeight};if (pos.x > range.maxX) {pos.x = range.maxX;}if (pos.x < range.minX) {pos.x = range.minX;}if (pos.y > range.maxY) {pos.y = range.maxY;}if (pos.y < range.minY) {pos.y = range.minY;}this.cover.style.left = pos.x + "px";this.cover.style.top = pos.y + "px";this.ctx.clearRect(0,0,this.imgwrap.offsetWidth,this.imgwrap.offsetHeight);let startX = pos.x - (imgwrap.left - document.documentElement.scrollLeft),startY = pos.y - (imgwrap.top - document.documentElement.scrollTop);this.ctx.drawImage(this.img,startX * this.imgTimesX,startY * this.imgTimesY,this.img.width * this.rectTimesX,this.img.height * this.rectTimesY,0,0,this.imgbox.offsetWidth,this.imgbox.offsetHeight);this.bigImage = this.canvas.toDataURL("image/png");},mouseover(e) {if (!this.init) {return false;}e = e || event;if (!this.scroll) {e.currentTarget.addEventListener("mousewheel",function(ev) {ev.preventDefault();},false);e.currentTarget.addEventListener("DOMMouseScroll",function(ev) {ev.preventDefault();},false);}this.cover.style.display = "block";this.canvas.style.display = "block";this.showImage = true;},mouseleave() {if (!this.init) {return false;}this.cover.style.display = "none";this.canvas.style.display = "none";this.showImage = false;},rotate(direction) {var orginImg = new Image();orginImg.crossOrigin = "Anonymous";orginImg.src = this.orginUrl;orginImg.onload = () => {this.rotateImg(orginImg, direction, this.step);};if (this.bigOrginUrl) {var bigOrginImg = new Image();orginImg.crossOrigin = "Anonymous";bigOrginImg.src = this.bigOrginUrl;bigOrginImg.onload = () => {this.rotateImg(bigOrginImg, direction, this.bigStep, true);};}},rotateImg(img, direction, step, isBig = false) {var min_step = 0;var max_step = 3;if (img == null) return;//img的高度和宽度不能在img元素隐藏后获取,否则会出错var height = img.height;var width = img.width;if (step == null) {step = min_step;}if (direction == "right") {step++;//旋转到原位置,即超过最大值step > max_step && (step = min_step);} else {step--;step < min_step && (step = max_step);}var canvas = document.createElement("canvas");//旋转角度以弧度值为参数var degree = (step * 90 * Math.PI) / 180;var ctx = canvas.getContext("2d");canvas.width = height;canvas.height = width;ctx.rotate(degree);ctx.drawImage(img, 0, -height);switch (step) {case 0:canvas.width = width;canvas.height = height;ctx.drawImage(img, 0, 0);break;case 1:canvas.width = height;canvas.height = width;ctx.rotate(degree);ctx.drawImage(img, 0, -height);break;case 2:canvas.width = width;canvas.height = height;ctx.rotate(degree);ctx.drawImage(img, -width, -height);break;case 3:canvas.width = height;canvas.height = width;ctx.rotate(degree);ctx.drawImage(img, -width, 0);break;}var newImg = canvas.toDataURL();if (isBig) {this.bigImgUrl = newImg;this.bigStep = step;this.initBox();} else {this.imgUrl = newImg;this.step = step;this.$nextTick(() => {this.initBox();});}}}
};
</script><style lang="scss" scoped>
.magnifier-box {width: 100%;height: 100%;text-align: center;overflow: hidden;.edit-wrap {top: 5px;right: 0;z-index: 9999999;background: rgba(0, 0, 0, 0.4);padding: 5px 15px 0 15px;border-radius: 15px;.rotate-left {display: inline-block;cursor: pointer;width: 16px;height: 16px;/*background: url(../rotate.png);*/background-size: 100% 100%;-moz-transform: scaleX(-1);-webkit-transform: scaleX(-1);-o-transform: scaleX(-1);transform: scaleX(-1);/*IE*/filter: FlipH;}.rotate-right {margin-left: 10px;cursor: pointer;display: inline-block;width: 16px;height: 16px;/*background: url(../rotate.png);*/background-size: 100% 100%;}}img {width: 100%;}.mouse-cover {position: fixed;background-color: rgba(0, 0, 0, 0.5);cursor: move;}/deep/.mouse-cover-canvas {position: fixed;left: 100%;top: 200px !important;width: 100%;height: 100%;}&.vertical {img {height: 100%;width: auto;}}
}
.big-image {border: 1px solid #eee;display: block;width: 498px;height: 498px;top: -1px;position: absolute;left: 498px;z-index: 99;
}
</style>

Carousel.vue(缩略图组件)

<template><div><div class="pic-box"><pic-zoom :url="pImgSrc" :scale="3"></pic-zoom></div><div class="box"><el-carousel height="96px" indicator-position="none" :interval="0"><el-carousel-item v-for="(item,i) in imagesList" :key="i"><divv-for="(img,index) in item.imgUrl":key="index"@click="getIndex(img.url)"class="img-url"><img :src="img.url" /></div></el-carousel-item></el-carousel></div></div>
</template>
<script>
import PicZoom from "./PicZoom";
export default {name: "Carousel",components: {PicZoom},data() {return {pImgSrc: ""};},props: {imgSrc: {type: String,default: ""},imagesList: {type: Array,default: function() {return [];}}},methods: {getIndex(imgSrc) {this.pImgSrc = imgSrc;}},watch: {imgSrc: {handler(aImgSrc, pImgSrc) {this.pImgSrc = aImgSrc;},immediate: true}}
};
</script>
<style lang="scss" scoped>
.box {width: 500px;height: 100px;overflow: hidden;margin-top: 10px;ul {position: absolute;width: 2000px;li {display: inline-block;list-style: none;width: 90px;height: 90px;background-color: white;margin-top: 15px;border: 1px solid #eee;overflow: hidden;margin-right: 10px;img {width: 100%;}}}
}
.pic-box {position:relative;width: 498px;height: 498px;border: 1px solid #eee;
}
/deep/ .mouse-cover-canvas {top: 200px !important;margin-top: 200px;
}.img-url {display: inline-block;border: 1px solid #eee;margin-right: 10px;&:nth-child(5) {margin-right: 0;}img {width: 90px;}
}
</style>

index.vue
页面引用代码:

<Carousel :imgSrc="imgSrc" :imagesList="imagesList" />

js部分:

import Carousel from "@/components/main/Carousel.vue";
export default {components: {Carousel,},data() {return {imgSrc: require("../../../assets/images/bp002-1.jpg"), //默认显示大图imagesList: [//缩略图:{imgUrl: [{ url: require("../../../assets/images/bp002-1.jpg") },{ url: require("../../../assets/images/bp002-2.jpg") },{ url: require("../../../assets/images/bp002-3.jpg") },{ url: require("../../../assets/images/bp002-4.jpg") },{ url: require("../../../assets/images/bp002-5.jpg") }]}],};},
};

Vue轮播缩略图(element ui)+鼠标悬浮放大图片(PicZoom)商城详情页图片展示相关推荐

  1. 【uni-app】swiper 实现纵向轮播,且支持鼠标滚轮滚动翻页

    前言 swiper 实现纵向轮播,且支持鼠标滚轮滚动翻页 操作方法(亲测可用) https://www.w3h5.com/post/607.html

  2. vue学习笔记-关于element ui 安装失败的问题解决

    今天学习vue时,对element ui进行安装,运行npm install element-ui -S 命令,出现报错: npm ERR! code ERESOLVE npm ERR! ERESOL ...

  3. bootstrap 轮播控制时间_【前端冷知识】如何封装一个图片轮播组件

    组件封装是一个前端工程师进阶的必经之路.组件封装是指Web页面上抽出来一个个包含模版(HTML).功能(Javascript)和样式(CSS)的单元.所以,今天的内容,我们将带你了解组件封装的开发思路 ...

  4. css3鼠标悬浮放大效果

    <!doctype html> <html><head><meta charset="utf-8"><title>css ...

  5. Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十六(商品排序,Thymeleaf快速入门,商品详情页的展示)

    Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十六(商品详情页的展示) 一.商品排序 1.完善页面信息 这是用来做排序的,默认按照综合排序 ...

  6. Vue商城——详情页功能

    详情页实现思路 点击商品进去详情页,根据点击请求更加详细的信息,要传过来goodsItem的iid,根据id去服务器请求更加详细的信息:配置路由映射关系,点击进行跳转,带参数传递跳转. 在GoodsL ...

  7. Vue轮播图插件---Vue-Awesome-Swiper

    轮播图插件 Vue-Awesome-Swiper 地址:https://github.com/surmon-china/vue-awesome-swiper 安装:npm install vue-aw ...

  8. 使用UI创建vue项目并添加element ui和axios

    目录 简介 Vue简单安装说明 项目创建步骤 总结 简介 因为最近一个项目需要使用SPA的方式,而前端选择使用vue来实现.所以最近重新看了下vue的相关知识,发现最新的vue项目可以在web中使用界 ...

  9. vue轮播组件--不插电手动粘贴版

    概述 轮播的原理是每一帧都选出一个当前元素,前一个元素,后一个元素然后排成一行,最后改变这三个元素的translate来触发css3的transition进行动画,当有touch事件的时候,要实时改变 ...

最新文章

  1. 解决cocos2dx 3.x 导入cocostudio的ui界面出现错位问题
  2. Nature封面论文创意被剽窃?UC圣迭戈付向东实名举报中科院研究员抄袭
  3. 中date转为string_股票数据获取篇(持续更新中...)
  4. java数组如何pop_Js数组的操作push,pop,shift,unshift等方法详细介绍
  5. Dynamics CRM2013/2015 检索实体属性的两种方式
  6. TCP/IP协议简介2
  7. perl xml dom中文乱码问题解决
  8. 绝地求生大逃杀,改配置
  9. linux 定时执行搅拌,Linux上定时shell脚本
  10. Postgresql kill用户进程
  11. Unity3D:粒子特效(Particle System)播放序列帧动画
  12. oracle全量增量_数据同步:全量与增量
  13. MOS在锂电池的核心原理
  14. 双绞线与计算机连接的接口是,rj45网络双绞线4根线接法详解
  15. RegShot(注册表比较工具)v2.0.1.68绿色中文版
  16. 上门洗车APP --- Android客户端开发 之 网络框架封装介绍(二)
  17. 使用ffmpeg直播推流总结
  18. 链乔教育在线|数字化工作管理工具—Notion(四):同步块(Synced block)
  19. TXS0102使用说明
  20. Java操作Excel三种方式POI、Hutool、EasyExcel

热门文章

  1. ubuntu 命令安装idea
  2. 【excel导出两级表头实现】
  3. (Java面试之知识点串烧)
  4. 如何修改tomcat默认端口号(详细步骤)
  5. 通知!明天下午欢迎大家和谷歌开发者团队相约学习 AI 模型加速方法与实践
  6. Excel | 常用函数(一)
  7. 教学一体化服务平台——学生选课系统需求分析
  8. Flink整合kafka的两阶段提交结论
  9. 依赖注入和控制反转的区别
  10. csdn博客转markdown