Vue实现电商网站商品放大镜效果示例

下面来详细讲解“Vue实现电商网站商品放大镜效果示例”的完整攻略,包括示例说明。

步骤一:搭建项目环境

首先需要安装Vue的开发环境,可以通过如下代码进行安装:

npm install -g @vue/cli

安装好后,新建一个基于Vue的项目:

vue create my-project

进入项目,安装依赖:

cd my-project
npm install

步骤二:准备图片资源

需要准备商品缩略图和放大后的大图两张图片,示例中假设分别为thumbnail.jpglarge.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技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • 微信小程序实现tabbar凹凸圆选中动画效果实例

    实现微信小程序的tabbar凹凸圆选中动画效果,可以分为以下几个步骤: 步骤1:准备好tabbar图标资源 在实现tabbar凹凸圆选中动画效果之前,需要准备好凹凸圆图标资源。可以使用Sketch等设计工具,画出带有选中和未选中状态的凹凸圆图标,并按照微信小程序要求的尺寸进行导出。 步骤2:创建tabbar页面 在小程序根目录下,创建一个tabbar页面。使…

    css 2023年6月9日
    00
  • 基于JS实现回到页面顶部的五种写法(从实现到增强)

    以下是详细讲解“基于JS实现回到页面顶部的五种写法(从实现到增强)”的完整攻略。 一、引言 在网页的开发过程中,经常会遇到需要让网页回到页面顶部的需求,比如用户滑动较长页面后,需要快速回到顶部,提高用户体验。本文将介绍基于JS实现回到页面顶部的五种写法,包括从最基本的实现到功能增强的高级写法。 二、基本实现 最基本的实现方式就是通过JS设置scrollTop…

    css 2023年6月10日
    00
  • 深入解析CSS中margin属性的使用

    深入解析CSS中margin属性的使用 在CSS中,margin属性用来控制元素的外边距。它可以帮助我们调整元素之间的间距,使得页面更加美观和整洁。在本文中,我们将深入讲解margin属性的使用,包括一些重要的概念和示例说明。 概念 在讲解margin属性之前,我们需要明确一些相关的概念: 外边距(margin):指元素与相邻元素之间的距离,它可以是正数、负…

    css 2023年6月9日
    00
  • HTML5单页面手势滑屏切换原理分析

    HTML5单页面手势滑屏切换原理分析 在前端开发中,HTML5单页面手势滑屏切换是一种常见的技术应用。本文将讲解实现该功能的原理和技术要点,以供开发者参考使用。 功能说明 HTML5单页面手势滑屏切换允许用户使用手势操作,在同一页面中切换不同的内容块。这种技术可以极大地提高用户体验和视觉效果,是一种常见有效的技术应用。 技术原理 实现HTML5单页面手势滑屏…

    css 2023年6月11日
    00
  • CSS中的背景部分编程学习教程

    作为网站的作者,以下是一份完整的CSS中背景编程学习教程攻略: 1. 学习背景相关属性 在学习CSS中的背景编程之前,必须先了解有哪些与背景相关的属性可供使用。CSS中与背景有关的主要属性如下: background-color:设置元素的背景颜色 background-image:设置元素的背景图片 background-repeat:设置背景图片是否重复…

    css 2023年6月9日
    00
  • 纯css实现立体摆放图片效果的示例代码

    下面是“纯css实现立体摆放图片效果”的攻略。 1. 准备图片资源 首先,在网站目录下准备多张图片资源,作为实现立体效果的图片。图片的格式可以是jpg、png等。 2. 新建html文件 在网站目录下新建一个html文件,以便将来在其中实现立体效果。可以在文件中添加一个div容器。 <!DOCTYPE html> <html> &lt…

    css 2023年6月10日
    00
  • 对CSS3选择器的研究(详解)

    对CSS3选择器的研究(详解) 1. CSS3选择器简介 CSS3选择器是描述样式如何应用于HTML文档中不同元素的一种机制。选择符使HTML文档和样式表关联在一起。选择器用于选择您希望应用样式表规则的HTML元素。 2. CSS3选择器分类 CSS3选择器主要分为以下几类: 2.1 元素选择器 最常用的选择器,通过元素名称选取HTML文档中的元素。例如: …

    css 2023年6月9日
    00
  • DIV随滚动条滚动而滚动的实现代码【推荐】

    这里给您详细讲解一下DIV随滚动条滚动而滚动的实现代码的完整攻略。 1. 安装jQuery插件 实现DIV随滚动条滚动而滚动,需要使用jQuery插件。如果您还没有安装jQuery插件,请先进行安装。 在HTML文件中插入jQuery插件的链接: <script src="https://cdn.bootcss.com/jquery/3.4.…

    css 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部