Vue图片放大镜组件的封装使用详解
1. 组件功能
该组件是一个基于Vue框架封装的图片放大镜组件。当用户鼠标移动到图片上时,鼠标正中心出现一个放大镜图层,能够实现对图片的放大查看。该组件主要由两部分组成:鼠标跟随图层、放大镜图层。
2. 组件使用
该组件的使用非常简单,以下是使用步骤:
2.1 引入组件
import Vue from 'vue'
import Magnifier from '@components/magnifier/Magnifier.vue'
Vue.component('magnifier', Magnifier)
在需要使用组件的地方引入该组件并注册它。
2.2 声明变量并绑定数据
data() {
return {
imageList: [{ // 图片列表
url: require('@/assets/images/1.jpg'), // 图片地址
name: '图片1' // 图片名
}]
}
},
声明一个imageList数组变量,并将需要显示的图片信息存入该变量中。
2.3 在模板中使用组件并绑定数据
<magnifier
v-for="(item, index) in imageList"
:key="index"
:origin-img="item.url"
:name="item.name"
:max-width="500"
:max-height="500"
:ratio="2.5"
></magnifier>
在模板中使用<magnifier>
标签,并传递需要的属性值。其中:
origin-img
表示需要显示的原图片地址。name
表示该图片的名称。max-width
表示放大镜图层的最大宽度。max-height
表示放大镜图层的最大高度。ratio
表示放大镜的比例。
3. 组件结构
该组件目录结构如下:
- Magnifier.vue
其中,Magnifier.vue是该组件的核心代码文件。
以下是组件代码的详细注释说明:
<template>
<div class="magnifier-wrap" ref="magnifierWrap" @mouseenter="showMagnifier" @mouseleave="hideMagnifier" @mousemove="moveMagnifier">
<!-- 原图 -->
<img class="origin-img" ref="originImg" :src="originImgSrc" :alt="name">
<!-- 放大镜图层 -->
<div class="magnifier-layer" ref="magnifierLayer" :style="{ 'width': maxWidth + 'px', 'height': maxHeight + 'px' }">
<img class="magnifier-img" :src="magnifierImgSrc" :style="{ 'width': magnifierWidth + 'px', 'height': magnifierHeight + 'px', 'left': magnifierLeft + 'px', 'top': magnifierTop + 'px' }">
</div>
</div>
</template>
<script>
export default {
name: 'Magnifier',
props: {
originImg: { // 原图地址
type: String,
required: true
},
name: { // 图片名称
type: String,
default: ''
},
maxWidth: { // 放大镜图层最大宽度
type: Number,
default: 500,
validator: (value) => value > 0
},
maxHeight: { // 放大镜图层最大高度
type: Number,
default: 500,
validator: (value) => value > 0
},
ratio: { // 放大倍数
type: Number,
default: 2,
validator: (value) => value > 0
}
},
data() {
return {
magnifierWidth: 0, // 放大镜宽度
magnifierHeight: 0, // 放大镜高度
magnifierLeft: 0, // 放大镜水平位置
magnifierTop: 0, // 放大镜垂直位置
magnifierShow: false, // 是否显示放大镜
originImgSrc: this.originImg, // 原图地址
magnifierImgSrc: this.originImg, // 放大镜图片地址
originWidth: 0, // 原图宽度
originHeight: 0 // 原图高度
}
},
methods: {
showMagnifier() { // 显示放大镜图层
this.magnifierShow = true
},
hideMagnifier() { // 隐藏放大镜图层
this.magnifierShow = false
},
moveMagnifier(e) { // 鼠标跟随
if (!this.magnifierShow) return
const wrapRect = this.$refs.magnifierWrap.getBoundingClientRect() // 获取整个组件容器的位置信息
const x = e.pageX - wrapRect.left // 获取鼠标在组件容器内的水平坐标
const y = e.pageY - wrapRect.top // 获取鼠标在组件容器内的垂直坐标
this.magnifierLeft = x - this.magnifierWidth / 2 // 设置放大镜的水平位置
this.magnifierTop = y - this.magnifierHeight / 2 // 设置放大镜的垂直位置
// 边界判断
if (this.magnifierLeft < 0) this.magnifierLeft = 0
else if (this.magnifierLeft > wrapRect.width - this.magnifierWidth) this.magnifierLeft = wrapRect.width - this.magnifierWidth
if (this.magnifierTop < 0) this.magnifierTop = 0
else if (this.magnifierTop > wrapRect.height - this.magnifierHeight) this.magnifierTop = wrapRect.height - this.magnifierHeight
}
},
mounted() {
// 图片加载完成后计算相关尺寸并进行初始化
this.$refs.originImg.onload = () => {
this.originWidth = this.$refs.originImg.clientWidth
this.originHeight = this.$refs.originImg.clientHeight
this.magnifierWidth = Math.floor(this.maxWidth / this.ratio)
this.magnifierHeight = Math.floor(this.maxHeight / this.ratio)
this.magnifierImgSrc = this.originImgSrc
this.$refs.magnifierLayer.style.backgroundImage = `url(${this.originImgSrc})`
this.magnifierShow = false
}
},
watch: {
originImg() { // 原图地址变动时重新初始化
this.originImgSrc = this.originImg
this.magnifierImgSrc = this.originImg
this.$refs.magnifierLayer.style.backgroundImage = `url(${this.originImgSrc})`
this.magnifierShow = false
}
}
}
</script>
<style scoped>
.magnifier-wrap {
position: relative;
cursor: none;
}
.origin-img {
max-width: 100%;
display: block;
border-radius: 5px;
}
.magnifier-layer {
position: absolute;
overflow: hidden;
/*background: rgba(255, 255, 255, 0.5);*/
border: 1px solid #ddd;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3);
border-radius: 5px;
z-index: 99;
display: none;
cursor: none;
}
.magnifier-layer .magnifier-img {
position: absolute;
display: inline-block;
}
</style>
4. 使用示例
4.1 示例1
以下是一个简单的使用示例:
<template>
<div class="app">
<div class="image-list">
<h3>图片列表</h3>
<magnifier
v-for="(item, index) in imageList"
:key="index"
:origin-img="item.url"
:name="item.name"
:max-width="500"
:max-height="500"
:ratio="2.5"
></magnifier>
</div>
</div>
</template>
<script>
import Magnifier from '@components/magnifier/Magnifier.vue'
export default {
name: 'App',
components: {
Magnifier
},
data() {
return {
imageList: [{ // 图片列表
url: require('@/assets/images/1.jpg'), // 图片地址
name: '图片1' // 图片名
}, {
url: require('@/assets/images/2.jpg'), // 图片地址
name: '图片2' // 图片名
}]
}
},
}
</script>
<style>
.app {
padding: 20px;
}
.image-list {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
h3 {
text-align: center;
width: 100%;
}
img {
margin-bottom: 20px;
}
</style>
在该示例中,我们引入了Magnifier组件,并声明了一个imageList数组,其中存储了需要显示的图片信息。接着,在模板中使用<magnifier>
标签并传递需要的属性,就可以展示图片放大镜了。
4.2 示例2
以下是另一个高级一些的使用示例,该示例中,我们可以通过拖拽图片来改变放大镜的位置:
<template>
<div class="app">
<div class="image-list">
<h3>图片列表</h3>
<magnifier
v-for="(item, index) in imageList"
:key="index"
:origin-img="item.url"
:name="item.name"
:max-width="500"
:max-height="500"
:ratio="2"
@mousedown="startDrag"
@mouseup="endDrag"
@mousemove="dragMove"
></magnifier>
</div>
</div>
</template>
<script>
import Magnifier from '@components/magnifier/Magnifier.vue'
export default {
name: 'App',
components: {
Magnifier
},
data() {
return {
imageList: [{ // 图片列表
url: require('@/assets/images/1.jpg'), // 图片地址
name: '图片1' // 图片名
}, {
url: require('@/assets/images/2.jpg'), // 图片地址
name: '图片2' // 图片名
}]
}
},
methods: {
startDrag(e) {
const magnifierLayer = e.target.parentNode.parentNode
magnifierLayer.style.cursor = 'move'
magnifierLayer.dragging = true
magnifierLayer.startX = e.clientX - magnifierLayer.offsetLeft
magnifierLayer.startY = e.clientY - magnifierLayer.offsetTop
},
endDrag(e) {
const magnifierLayer = e.target.parentNode.parentNode
magnifierLayer.style.cursor = 'none'
magnifierLayer.dragging = false
},
dragMove(e) {
const magnifierLayer = e.target.parentNode.parentNode
if (!magnifierLayer.dragging) return
const x = e.clientX - magnifierLayer.startX
const y = e.clientY - magnifierLayer.startY
magnifierLayer.style.left = `${x}px`
magnifierLayer.style.top = `${y}px`
}
}
}
</script>
<style>
.app {
padding: 20px;
}
.image-list {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
h3 {
text-align: center;
width: 100%;
}
img {
margin-bottom: 20px;
}
</style>
在该示例中,我们通过添加拖拽事件来实现了更加丰富的用户体验。具体实现细节可以参见代码中的注释。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue图片放大镜组件的封装使用详解 - Python技术站