vue3封裝放大鏡元件的例項程式碼
阿新 • • 發佈:2021-09-22
目錄
- 元件基礎結構
- 目的:實現圖片放大鏡功能
- 安裝use
- 功能實現
- 完整程式碼
- 總結
元件基礎結構
結尾有完整程式碼可直接複製使用
目的:封裝圖片預覽元件,實現滑鼠懸停切換效果
落地程式碼:
<template> <div class="goods-image"> <http://www.cppcns.comdiv class="middle"> <img :src="images[currIndex]" alt="vue3封裝放大鏡元件的例項程式碼"> </div> <ul class="small"> <li v-for="(img,i) in images" :key="img" :class="{active:i===currIndex}"> <img @mouseenter="currIndex=i" :src="img" abXmpGfArJlt="vue3封裝放大鏡元件的例項程式碼"> </li> </ul> </div> </template> <script> import { ref } from 'vue' export default { name: 'GoodsImage',props: { images: { type: Array,default: () => [] } },setup (props) { const currIndex = ref(0) return { currIndex } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; .middle { width: 400px; height: 400px; background: #f5f5f5; } .small { width: 80px; li { width: 68px; height: 68px; margin-left: 12px; margin-bottom: 15px; cursor: pointer; &:hover,&.active { border: 2px solid @xtxColor; } } } } </style>
圖片放大鏡
目的:實現圖片放大鏡功能
步驟:
- 首先準備大圖容器和遮罩容器
- 然後使用@vueuse/core的useMouseInElement方法獲取基於元素的偏移量
- 計算出 遮罩容器定位與大容器背景定位 暴露出資料給模板使用
落地程式碼:
<template> <div class="goods-image"> + // 實現右側大圖佈局效果(背景圖放大4倍) + <div class="large" :style="[{backgroundImage:`url(${images[currIndex]})`}]"></div> <div class="middle"> <img :src="images[currIndex]" alt="vue3封裝放大鏡元件的例項程式碼"> + // 準備待移動的遮罩容器 + <div class="layer"></div> </div> <ul class="small"> <li v-for="(img,i) in images" :key="img" :class="{active:i===currIndex}"> <img @mouseenter="currIndex=i" :src="img" alt="vue3封裝放大鏡元件的例項程式碼"> </li> </ul> </div> </template> <script> import { ref } from 'vue' export default { name: 'GoodsImage',setup (props) { const currIndex = ref(0) return { currIndex } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; + z-index: 500; + // 右側大圖樣式 + .large { + position: absolute; + top: 0; + left: 412px; + width: 400px; + height: 400px; + box-shadow: 0 0 10px rgba(0,0.1); + background-repeat: no-repeat; + background-size: 800px 800px; + background-color: #f8f8f8; + } .middle { width: 400px; height: 400px; background: #f5f5f5; + position: relative; + cursor: move; + // 遮罩樣式 + .layer { + width: 200px; + height: 200px; + background: rgba(0,.2); + left: 0; + top: 0; + position: absolute; + } } .small { width: 80px; li { width: 68px; height: 68px; margin-left: 12px; margin-bottom: 15px; cursor: pointer; &:hover,&.active { border: 2px solid @xtxColor; } } } } </style>
安裝vueuse
npm i @vueuse/[email protected]
目前5.3.0版本相對穩定
vueuse提供的監聽進入指定範圍方法的基本使用
import { useMouseInElement } from '@vueuse/core' const { elementX,elementY,isOutside } = useMouseInElement(target)
方法的引數target表示被監聽的DOM物件;返回值elementX,elementY表示被監聽的DOM的左上角的位置資訊left和top;isOutside表示是否在DOM的範圍內,true表示在範圍之外。false表示範圍內。
功能實現
<div v-if="isShow" class="large" :style="[{ backgroundImage: `url(${images[currIndex]})` },bgPosition]"></div> <div class="middle" ref="target"> <img :src="images[currIndex]" alt="vue3封裝放大鏡元件的例項程式碼" /> <div class="layer" v-if="isShow" :style="[position]"></div> </div> setup () { // 被監聽的區域 const target = ref(null) // 控制遮罩層和預覽圖的顯示和隱藏 const isShow = ref(false) // 定義遮罩的座標 const position = reactive({ left: 0,top: 0 }) // 右側預覽大圖的座標 const bgPosition = reactive({ backgroundPositionX: 0,backgroundPositionY: 0 }) return { position,bgPosition,target,isShow } }
const { elementX,isOutside } = useMouseInElement(target) // 基於偵聽器偵聽值的變化 watch([elementX,isOutside],() => { // 通過標誌位控制顯示和隱藏 isShow.value = !isOutside.value if (isOutside.value) return // X方向座標範圍控制 if (elementX.value < 100) { // 左側 position.left = 0 } else if (elementX.value > 300) { // 右側 position.left = 200 } else { // 中間 position.left = elementX.value - 100 } // Y方向座標範圍控制 if (elementY.value < 100) { position.top =http://www.cppcns.com 0 } else if (elementY.value > 300) { position.top = 200 } else { position.top = elementY.value - 100 } // 計算預覽大圖的移動的距離 bgPosition.backgroundPositionX = -position.left * 2 + 'px' bgPosition.backgroundPositionY = -position.top * 2 + 'px' // 計算遮罩層的位置 position.left = position.left + 'px' position.top = position.top + 'px' })
完整程式碼
<template>
<div class="goods-image">
<div v-if="isShow" class="large" :style="[{ backgroundImage: `url(${images[currIndex]})` },bgPosition]"></div>
<div class="middle" ref="target">
<img :src="images[currIndex]" alt="vue3封裝放大鏡元件的例項程式碼" />
<div class="layer" v-if="isShow" :style="[position]"></div>
</div>
<ul class="small">
<li v-for="(img,i) in images" :key="img" :class="{ active: i === currIndex }">
<img @mouseenter="currIndex = i" :src="img" alt="vue3封裝放大鏡元件的例項程式碼" />
</li>
</ul>
</div>
</template>
<script>
import { ref,watch,reactive } from 'vue'
import { useMouseInElement } from '@vueuse/core'
export default {
name: 'GoodsImage',setup (props) {
const currIndex = ref(0)
const target = ref(null)
const isShow = ref(false)
const position = reactive({
left: 0,top: 0
})
const bgPosition = reactive({
backgroundPositionX: 0,backgroundPositionY: 0
})
const { elementX,isOutside } = useMouseInElement(target)
watch([elementX,() => {
isShow.value = !isOutside.value
if (isOutside.value) return
if (elementX.value <= 100) {
position.left = 0
} else if (elementX.value >= 300) {
position.left = 200
} else {
position.left = elementX.value - 100
}
if (elementY.value <= 100) {
position.top = 0
} else if (elementY.value >= 300) {
position.top = 200
} else {
position.top = elementY.value - 100
}
bgPosition.backgroundPositionX = -position.left * 2 + 'px'
bgPosition.backgroundPositionY = -position.top * 2 + 'px'
position.left += 'px'
position.top += 'px'
})
return { currIndex,isShow,position,bgPosition }
}
}
</script>
<style scoped lang="less">
.goods-image {
width: 480px;
height: 400px;
position: relative;
display: flex;
z-index: 500;
.large {
position: absolute;
top: 0;
left: 412px;
width: 400px;
height: 400px;
box-shadow: 0 0 10px rgba(0,0.1);
background-repeat: no-repeat;
background-size: 800px 800px;
background-color: #f8f8f8;
}
.middle {
width: 400px;
height: 400px;http://www.cppcns.com
background: #f5f5f5;
position: relative;
cursor: move;
.layer {
width: 200px;
height: 200px;
background: rgba(0,.2);
left: 0;
top: 0;
position: absolute;
}
}
.small {
width: 80px;
li {
width: 68px;
height: 68px;
margin-left: 12px;
margin-bottom: 15px;
cursor: pointer;
&:hover,&.active {
border: 2px solid @xtxColor;
}
}
}
}
</style>
總結
到此這篇關於vue3封裝放大鏡元件的文章就介紹到這了,更多相關vue3封裝放大鏡元件內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!