Vue3 实现产品图片放大器

Vue3 实现类似淘宝、京东产品详情图片放大器功能

环境:vue3+ts+vite

1.创建picShow.vue组件

javascript 复制代码
<script lang="ts" setup>
import {ref, computed} from 'vue'
import {useMouseInElement} from '@vueuse/core'

/*获取父组件的传值*/
defineProps<{
    images: string[]
}>()
// 当前显示的图片索引
let active = ref(0)
// ref 获取 DOM 元素的位置
const target = ref(null)
// isisOutside为 true 的时候代表鼠标未进入目标元素,为 false 时代表鼠标进入目标元素
const {elementX, elementY, isOutside} = useMouseInElement(target)
// 遮罩半透明图在商品大图中的坐标位置
const position = computed(() => {
    let x = elementX.value - 70
    let y = elementY.value - 70
    if (x <= 0) x = 0
    if (x >= 140) x = 140
    if (y <= 0) y = 0
    if (y >= 140) y = 140
    return {x, y}
})
</script>
<template>
    <div class="product-image">
        <!-- 放大 -->
        <div class="large" :style="[{ backgroundImage: `url(${images[active]})`,
          backgroundPosition: `-${position.x * 2}px -${position.y * 2}px`
        }]" v-show="!isOutside"></div>
        <div ref="target" class="middle">
            <img :src="images[active]" alt=""/>
            <!-- 遮罩层 -->
            <div class="layer" v-show="!isOutside" :style="{ left: `${position.x}px`, top: `${position.y}px` }"></div>
        </div>
        <ul class="small">
            <li v-for="(item, index) in images" :key="item"
                    :class="{ active: index === active }"
                    @mouseenter="active = index">
                <img :src="item" alt=""/>
            </li>
        </ul>
    </div>
</template>

<style lang="scss" scoped>
.product-image {
  position: relative;
  z-index: 500;
  .large {
    position: absolute;
    top: 0;
    left: 290px;
    width: 500px;
    height: 500px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    background-repeat: no-repeat;
    background-size: 156% 156%;
    background-color: #f8f8f8;
  }
  .middle {
    width: 280px;
    height: 280px;
    background: #f5f5f5;
    position: relative;
    cursor: move;
    .layer {
      width: 140px;
      height: 140px;
      background: rgba(0, 0, 0, 0.2);
      left: 0;
      top: 0;
      position: absolute;
    }
    img{
      width: 280px;
      height: 280px;
    }
  }
  .small {
    width: 280px;
    display: flex;
    margin-top: 5px;
    li {
      width: 70px;
      height: 70px;
      cursor: pointer;
      list-style: none;
      img{
        width: 70px;
        height: 70px;
      }
    }
  }
}
</style>

2.在其他页面引用组件picShow.vue

javascript 复制代码
<div class="product-info">
   <div class="media">
        <PicShow :images="picList"/>
    </div>
</div>

//js部分
import PicShow from "@/components/picShow.vue";
const picList=[
    '/src/assets/images/contactus01.jpg',
    '/src/assets/images/contactus02.jpg',
    '/src/assets/images/contactus03.jpg',
    '/src/assets/images/contactus04.jpg',
]

效果:

相关推荐
何以解忧,唯有..6 分钟前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
软件聚导航1 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
恋猫de小郭1 小时前
看懂大模型架构术语,帮助你理解目前常见的大模型开源架构
前端·人工智能·ai编程
yma162 小时前
通过提示词实现GitHub Pages 和 Nginx 双部署竟然这么简单?
前端
前端 贾公子2 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
可乐鸡翅yeah_2 小时前
第三方接口对接 M3U8 流媒体排坑实战,解决外部服务商流兼容难题
前端·javascript·python·django·html·m3u8·m3u8在线
GoppViper2 小时前
RDF资源描述框架深度解析:语义Web的数据基石与实战逻辑
前端·数据库
郑州光合科技余经理2 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
IT_陈寒2 小时前
Vue的嵌套组件竟然吃掉了我的事件?
前端·人工智能·后端
默_笙2 小时前
🏠 「LLM Notes」:我用 Next.js + Redis 给自己造了个笔记博客
前端·javascript