下面来详细讲解“Vue实现电商网站商品放大镜效果示例”的完整攻略,包括示例说明。
步骤一:搭建项目环境
首先需要安装Vue的开发环境,可以通过如下代码进行安装:
npm install -g @vue/cli
安装好后,新建一个基于Vue的项目:
vue create my-project
进入项目,安装依赖:
cd my-project
npm install
步骤二:准备图片资源
需要准备商品缩略图和放大后的大图两张图片,示例中假设分别为thumbnail.jpg
和large.jpg
。
步骤三:编写组件
组件分为两个部分:缩略图和放大镜。
缩略图部分
缩略图部分包含两个元素:缩略图和鼠标悬浮时的遮罩层,示例如下:
<template>
<div class="thumbnail-wrapper">
<img
:src="thumbnail"
:style="{width: thumbnailWidth + 'px', height: thumbnailHeight + 'px'}"
@mouseover="handleMouseOver"
@mouseout="handleMouseOut"
ref="thumbnail"
/>
<div
class="mask"
:style="{width: thumbnailWidth + 'px', height: thumbnailHeight + 'px', display: maskDisplay}"
ref="mask"
/>
</div>
</template>
<script>
export default {
props: {
thumbnail: String, // 缩略图的地址
thumbnailWidth: Number, // 缩略图的宽度
thumbnailHeight: Number // 缩略图的高度
},
data() {
return {
maskDisplay: 'none' // 初始时遮罩层不显示
}
},
methods: {
handleMouseOver() {
// 鼠标悬浮时显示遮罩层
this.maskDisplay = 'block'
},
handleMouseOut() {
// 鼠标移开时隐藏遮罩层
this.maskDisplay = 'none'
}
}
}
</script>
放大镜部分
放大镜部分包含三个元素:放大镜的容器、放大镜内部的大图以及用于遮盖的小框,示例如下:
<template>
<div
class="zoom-wrapper"
:style="zoomWrapperStyle"
ref="zoomWrapper"
>
<img
class="large-img"
:src="large"
:style="{width: largeWidth + 'px', height: largeHeight + 'px'}"
ref="largeImg"
@load="handleLoad"
@mousemove="handleMouseMove"
@mouseout="handleMouseOut"
/>
<div
class="small-box"
:style="{width: smallBoxWidth + 'px', height: smallBoxHeight + 'px', display: smallBoxDisplay}"
ref="smallBox"
/>
</div>
</template>
<script>
export default {
props: {
large: String, // 大图的地址
largeWidth: Number, // 大图的宽度
largeHeight: Number, // 大图的高度
zoomScale: Number // 放大倍数
},
data() {
return {
zoomWrapperStyle: {}, // 放大镜容器的样式
smallBoxDisplay: 'none', // 初始时小框不显示
smallBoxWidth: 0, // 小框的宽度
smallBoxHeight: 0, // 小框的高度
largeImgWidth: 0, // 大图的宽度
largeImgHeight: 0, // 大图的高度
largeImgLoaded: false // 大图是否加载完成的标志
}
},
methods: {
handleLoad() {
// 大图加载完成后需要根据缩略图设置放大倍数
const thumbnail = this.$parent.$refs.thumbnail
const thumbnailRect = thumbnail.getBoundingClientRect()
const zoomScale = this.zoomScale
const smallBoxWidth = thumbnailRect.width / zoomScale
const smallBoxHeight = thumbnailRect.height / zoomScale
const largeImgWidth = this.$refs.largeImg.clientWidth
const largeImgHeight = this.$refs.largeImg.clientHeight
this.smallBoxWidth = smallBoxWidth
this.smallBoxHeight = smallBoxHeight
this.largeImgWidth = largeImgWidth
this.largeImgHeight = largeImgHeight
this.zoomWrapperStyle = {
width: thumbnailRect.width + 'px',
height: thumbnailRect.height + 'px',
position: 'absolute',
left: thumbnailRect.left + thumbnailRect.width + 20 + 'px'
}
this.largeImgLoaded = true
},
handleMouseMove(event) {
if (!this.largeImgLoaded) {
return
}
const smallBox = this.$refs.smallBox
const largeImg = this.$refs.largeImg
const zoomScale = this.zoomScale
const smallBoxWidth = this.smallBoxWidth
const smallBoxHeight = this.smallBoxHeight
const largeImgWidth = this.largeImgWidth
const largeImgHeight = this.largeImgHeight
const thumbnail = this.$parent.$refs.thumbnail
const thumbnailRect = thumbnail.getBoundingClientRect()
const x = event.clientX - thumbnailRect.left - smallBoxWidth / 2
const y = event.clientY - thumbnailRect.top - smallBoxHeight / 2
let top, left
if (x < 0) {
left = 0
} else if (x + smallBoxWidth > thumbnailRect.width) {
left = thumbnailRect.width - smallBoxWidth
} else {
left = x
}
if (y < 0) {
top = 0
} else if (y + smallBoxHeight > thumbnailRect.height) {
top = thumbnailRect.height - smallBoxHeight
} else {
top = y
}
smallBox.style.display = 'block'
smallBox.style.top = top + 'px'
smallBox.style.left = left + 'px'
const dWidth = largeImgWidth - this.zoomWrapperStyle.width.slice(0, -2)
const dHeight = largeImgHeight - this.zoomWrapperStyle.height.slice(0, -2)
largeImg.style.top = -dHeight * top / thumbnailRect.height * zoomScale + 'px'
largeImg.style.left = -dWidth * left / thumbnailRect.width * zoomScale + 'px'
},
handleMouseOut() {
const smallBox = this.$refs.smallBox
smallBox.style.display = 'none'
}
}
}
</script>
步骤四:使用组件
在父组件中引入缩略图和放大镜组件,并传递相应的参数即可,示例代码:
<template>
<div class="product">
<thumbnail
:thumbnail="thumbnail"
:thumbnail-width="120"
:thumbnail-height="120"
/>
<zoom
:large="large"
:large-width="600"
:large-height="600"
:zoom-scale="3"
/>
</div>
</template>
<script>
import Thumbnail from './Thumbnail'
import Zoom from './Zoom'
export default {
components: {
Thumbnail,
Zoom
},
data() {
return {
thumbnail: 'thumbnail.jpg',
large: 'large.jpg'
}
}
}
</script>
示例说明一:使用插件vue-awesome-swiper做为缩略图部分
若要将此效果集成到电商网站上,缩略图可使用插件vue-awesome-swiper实现轮播效果,示例代码:
<template>
<div class="swiper-container" :style="{width: thumbnailWidth + 'px', height: thumbnailHeight + 'px'}">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="(item, index) in thumbs" :key="index">
<img :src="item" />
</div>
</div>
</div>
</template>
<script>
import Swiper from 'vue-awesome-swiper'
import 'swiper/css/swiper.css'
export default {
components: {
Swiper
},
props: {
thumbs: Array, // 缩略图的数组
thumbnailWidth: Number, // 缩略图的宽度
thumbnailHeight: Number // 缩略图的高度
}
}
</script>
在父组件中使用缩略图部分的时候,示例代码如下:
<thumbnail
:thumbs="thumbs"
:thumbnail-width="200"
:thumbnail-height="200"
/>
示例说明二:使用插件vue-the-mask限制放大镜的滚动范围
若要防止放大镜超出缩略图的范围,可使用插件vue-the-mask实现遮罩功能,如下:
首先安装插件:
npm install --save vue-the-mask
引入插件:
import { VueTheMask } from 'vue-the-mask'
Vue.use(VueTheMask)
然后在放大镜容器上添加遮罩:
<template>
<div v-the-mask class="zoom-wrapper" :style="zoomWrapperStyle" ref="zoomWrapper">
<!-- 省略其余代码 -->
</div>
</template>
在使用遮罩(v-the-mask)的时候需要保证放大镜和遮罩的z-index值在同一个层级,这样才能起到正确的遮罩效果。
使用完整的效果代码示例:
<template>
<div class="product">
<thumbnail :thumbs="thumbs" :thumbnail-width="200" :thumbnail-height="200">
<template v-slot:default="{ current }">
<img class="zoom" :src="current" alt="" />
</template>
</thumbnail>
<zoom :large="large" :large-width="600" :large-height="600" :zoom-scale="3" />
</div>
</template>
<script>
import Thumbnail from './Thumbnail'
import Zoom from './Zoom'
import { VueTheMask } from 'vue-the-mask'
export default {
components: {
Thumbnail,
Zoom
},
mixins: [VueTheMask.mixin],
data() {
return {
thumbs: ['thumbnail1.jpg', 'thumbnail2.jpg', 'thumbnail3.jpg'],
large: 'large.jpg'
}
}
}
</script>
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue实现电商网站商品放大镜效果示例 - Python技术站