【精品】基于VUE3的 电商详情 图片显示模块

news2024/9/24 9:22:38

效果

在这里插入图片描述

组件

<template>
    <div class="goods-imgs">
        <div class="imgs-show">
            <img :src="mainImage" alt="大图" />
        </div>
        <ul class="img-thumbnail">
            <li v-for="(item, index) in imageList" :key="index" class="img-li" :style="imgStyle"
                @click="changeImg(item, index)">
                <img :class="index === imgActiveIndex ? 'img_activeBorder' : ''" :src="item" alt="小图" />
            </li>
        </ul>
    </div>
</template>
<script setup lang="ts">
import { ref, Ref, onBeforeMount, computed } from 'vue'

const props = defineProps({
    mainImage: String,
    imageList: Array
})

const mainImage = ref(props.mainImage)

const imageList: Ref<any> = ref(props.imageList)


const imgActiveIndex = ref(0) // 当前移动图片的索引值
const imgDistance = ref(0) // 移动的距离
const allDistance = ref(0) // 总移动距离

const changeImg = (item: string, index: number) => {
    mainImage.value = item
    imgActiveIndex.value = index
}

const imgLeft = () => {
    if (imgActiveIndex.value > 0) {
        imgActiveIndex.value-- // 索引值-1
        imageList.value.forEach((item: string, index: number) => {
            // 循环小图,通过判断索引值赋值给大图
            if (imgActiveIndex.value === index) {
                mainImage.value = item
            }
        })
    }
    if (imgActiveIndex.value >= 4) {
        var index1 = 0
        const temp = window.setInterval(() => {
            // 利用定时器实现图片左右移动的动画效果
            if (index1 < 33) {
                // 移动次数(33次)
                imgDistance.value += 2 // 每次向左移动的距离 (移动总距离为33*imgDistance)
                index1++
                return
            } else {
                window.clearInterval(temp) // 移动完清除定时器
            }
        }, 10)
    }
}
const imgRight = () => {
    if (imgActiveIndex.value < imageList.value.length - 1) {
        imgActiveIndex.value++
        imageList.value.forEach((item: string, index: number) => {
            if (imgActiveIndex.value === index) {
                mainImage.value = item
            }
        })
        if (imgActiveIndex.value >= 5) {
            allDistance.value = -66 * (imgActiveIndex.value - 4)
            var index2 = 0
            const temp = window.setInterval(() => {
                if (index2 < 33) {
                    imgDistance.value -= 2 // 每次向右移动的距离
                    index2++
                    return
                } else {
                    window.clearInterval(temp)
                }
            }, 10)
        }
    } else if (imgActiveIndex.value === imageList.value.length - 1) {
        // 到达最后一张图片,再点击跳转回第一张
        imgActiveIndex.value = 0
        mainImage.value = imageList.value[0]
        var index3 = 0
        const temp = window.setInterval(() => {
            // 利用定时器实现图片左右移动的动画效果
            if (index3 < Math.abs(allDistance.value / 2)) {
                // 取绝对值再除
                imgDistance.value += 2 // 每次向左移动的距离 (移动总距离为33*imgDistance)
                index3++
                return
            } else {
                window.clearInterval(temp) // 移动完清除定时器
            }
        }, 1)
    }
}

const imgStyle = computed(() => {
    return {
        transform: `translate3d(${imgDistance.value}px, 0, 0)`, // 计算移动的距离(x,y,z)
    }
})
</script>

<style scoped lang="less">
.goods-imgs {
    margin-top: 2px;
    width: 100%;
    height: 435px;

    .imgs-show {
        width: 100%;

        height: 350px;

        img {
            width: 100%;
            height: 100%;
        }
    }

    .img-thumbnail {
        margin-top: 8px;
        position: relative;
        display: flex;
        width: 100%;
        height: 85px;
        overflow: hidden;
        overflow-x: scroll;
        list-style: none;

        .img-li {
            float: left;
            margin: 0 8px;
            cursor: pointer;

            img {
                width: 100%;
                height: 100%;
            }

            .img_activeBorder {
                border: 3px solid #0dcc73;
            }
        }
    }
}
</style>

使用

<!-- 个人主页 -->
<template >
   <GoodsImage :mainImage="mainImage" :imageList="imageList"></GoodsImage>
</template>

<script setup lang="ts">
//自定义组件
import GoodsImage from '@/components/GoodsImage.vue'
import { ref} from 'vue'

const mainImage = ref(
    'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
)
const imageList = ref([
    'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
    'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
    'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
    'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
    'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
    'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
    'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
    'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
    'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
    'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
    'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
])
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/930874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

freertos之任务调度算法

介绍 所谓调度算法&#xff0c;就是怎么确定哪个就绪态的任务可以切换为运行状态。 通过配置文件FreeRTOSConfig.h的三个配置项来配置调度算法&#xff1a;configUSE_PREEMPTION &#xff08;是否抢占&#xff09; configUSE_TIME_SLICING &#xff08;是否轮转&#xff09; c…

Linux操作系统--常用指令(文件目录类指令)

(1).pwd指令 功能:显示当前工作目录的绝对路径。 如果你使用cd命令进行切换的时候不知道到了哪里,就可以使用该指令输出路径查看。 (2).cd命令 功能:用于切换路径 语法: cd + 路径(路径可以指绝对路径,也可以是相对路径)

记录--一个炫酷的css动画

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 最近有一个需求&#xff0c;要我实现一个动画效果&#xff0c;效果如下 简单分析了一下效果&#xff0c;是一个3d的效果&#xff0c;首先是一个圆&#xff0c;接着是两段圆环&#xff0c;第三层是一堆…

WordPress使用子主题插件 Child Theme Wizard,即使主题升级也能够保留以前主题样式

修改WordPress网站样式&#xff0c;主题升级会导致自己定义设置的网站样式丢失&#xff0c;还需要重新设置&#xff0c;很繁琐工作量大&#xff0c;发现在WordPress 中有Child Theme Wizard子主题插件&#xff0c;使用Child Theme Wizard子主题插件&#xff0c;即使主题升级&am…

uni、js——点击与禁用(不可点击)、动态样式class

案例 没约满的时间可以点击进行选择&#xff0c;约满的就不能选择了。选择完之后变色变字。 核心思想就是创建一个第三方变量存起来&#xff0c;点击谁就存到第三方&#xff0c;在根据这个进行判断。 代码 <template><view class"content"><view cl…

基于JSP+Servlet+Mysql网上商城

基于JSPServletMysql网上商城 一、系统介绍二、功能展示三、其它四.获取源码 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于JSPServlet的网上商城 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技术&#xff1a;HTML、CSS、…

卷轴模式解析:如何实现用户留存、引流拓客

随着现代技术的不断发展和数字货币市场的日益成熟&#xff0c;越来越多的数字货币项目被推向市场。而消费者需求日益复杂&#xff0c;单一的玩法模式已经不能满足消费者追求更好购物体验的需求。电商平台需要尊重消费者的意愿&#xff0c;满足消费者的多样化需求&#xff0c;这…

vue组装模板(侧边栏+顶部+主体)--项目阶段4

目录 一、前言介绍 二、结构解析 三、页面拆分 &#xff08;一&#xff09;页面拆分 1.侧边栏页面&#xff08;固定&#xff09;--Aside.vue 2.顶部页面&#xff08;固定&#xff09;--Header.vue 3.主体页面&#xff08;不固定的&#xff09;--示例用UserView…

启动metastore服务报错

启动Metastore的时候报错&#xff1a; 简略的报错信息&#xff1a; MetaException(message:Error creating transactional connection factory)Caused by: MetaException(message:Error creating transactional connection factory)Caused by: javax.jdo.JDOFatalInternalExce…

识别图片中的文字

前言 PearOCR 是一款免费无限制网页版文字识别工具。 优点如下&#xff1a; 免费&#xff1a;完全免费&#xff0c;没有任何次数、大小限制&#xff0c;可以无限使用&#xff1b; 安全&#xff1a;全部数据本地运算&#xff0c;所有图片均不会被上传&#xff1b; 智能&#xf…

CRM的销售预测有什么用?如何操作?

销售预测对于销售团队非常重要&#xff0c;它可以估计未来一段时间内的销售量和收入&#xff0c;帮助销售人员制定基于数据的决策&#xff0c;提高销售业绩。CRM可以收集和分析销售数据&#xff0c;并进行销售预测。下面说说&#xff0c;什么是销售预测&#xff1f;CRM如何进行…

Buzz语音转文字安装使用(含Whisper模型下载)

简介&#xff1a; Transcribe and translate audio offline on your personal computer. Powered by OpenAI’s Whisper. 转录和翻译音频离线在您的个人计算机。由OpenAI的Whisper提供动力。 可以简单理解为QT的前端界面&#xff0c;python语言构建服务端&#xff0c;使用Whis…

Vant 4中的van-picker选择总是第一个的解决办法

Vant 4中的van-picker选择总是第一个的解决办法 官方demo <van-fieldv-model"fieldValue"is-linkreadonlylabel"城市"placeholder"选择城市"click"showPicker true" /> <van-popup v-model:show"showPicker" ro…

netty运行一段时间报错:java.io.IOException: 打开的文件过多

报错详细内容如下&#xff1a; java.io.IOException: 打开的文件过多at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:421)at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSo…

APP Binder客户端调用全流程分析

现在要搞明白JAVA层app调用跨进程的Service接口时&#xff0c;它的binder是怎样从Java->jni-->native--->binder驱动的这条链路&#xff1a;就是上图中的左半部分从上至下的流程。所以切入点在于&#xff0c;如app调用另一个进程的Service接口的getString&#xff08;…

Spring集成【MyBatis】和【PageHelper分页插件】整合---详细介绍

一&#xff0c;spring集成Mybatis的概念 Spring 整合 MyBatis 是将 MyBatis 数据访问框架与 Spring 框架进行集成&#xff0c;以实现更便捷的开发和管理。在集成过程中&#xff0c;Spring 提供了许多特性和功能&#xff0c;如依赖注入、声明式事务管理、AOP 等 它所带来给我们的…

安全学习DAY19_小程序信息打点

信息打点-小程序应用&解包反编译&抓包&静态分析&源码架构 文章目录 信息打点-小程序应用&解包反编译&抓包&静态分析&源码架构本节知识&思维导图本节使用到的链接&工具 小程序获取-各大平台&关键字搜索小程序-模版测试上线&源码…

如何开启esxi主机的ssh远程连接

环境&#xff1a;esxi主机&#xff0c;说明&#xff1a;esxi主机默认ssh是不开启的&#xff0c;需要人工手动启动&#xff0c;也可以设置同esxi主机一起开机启动。 1、找到esxi主机&#xff0c;点击“配置”那里&#xff0c;再点击右边的属性&#xff0c;如图所示&#xff1a; …

java属性映射使用MapStruct的坑

目录 1.实体类和映射类只加注解Data 2.将Data换成getter和setter后build 3.那么此时我把getter和setter换成lombok的getter和setter 1.实体类和映射类只加注解Data 映射关系类 这个时候运行 提示源参数中不存在 注意这个文件夹 2.将Data换成getter和setter后build package c…

Python如何进行基本的数学运算

Python进行基本的数学运算 Python是一门功能强大且易于学习的编程语言&#xff0c;它不仅可以用于开发应用程序&#xff0c;还可以用于执行各种数学运算。让我们一起来看看如何在Python中进行基本的数学运算。 加法、减法、乘法和除法 Python支持常见的加法、减法、乘法和除…