当前位置: 首页 > news >正文

Vue 3:基于按钮切换动态图片展示(附Demo)

目录

  • 前言
  • 1. Demo
  • 2. 升级Demo
  • 3. 终极Demo

前言

原先写过类似的知识点:

  1. 详细分析el-breadcrumb 面包屑的基本知识(附Demo)
  2. 详细分析el-card中的基本知识(附Demo)

本篇博客将介绍如何通过点击按钮切换不同的图片,并优化交互体验,使页面更流畅、响应更快

主要的知识点:

  • Vue 3 组件化开发 - 通过 setup 组合式 API 进行数据管理
  • 动态绑定 class - 根据当前选中的图片高亮按钮
  • 过渡动画 transition - 让图片切换更流畅
  • 图片预加载 - 避免切换时的卡顿
  • 样式优化 - 让按钮和图片展示更美观

1. Demo

最初始的版本Demo:

<template><div><!-- 按钮组 --><div class="button-group"><button v-for="image in images" :key="image.id" @click="currentImage = image.src">{{ image.label }}</button></div><!-- 动态展示图片 --><div class="image-container"><img v-if="currentImage" :src="currentImage" alt="Dynamic Image" /></div></div>
</template><script setup>
import { ref } from 'vue'// 当前选中的图片
const currentImage = ref(null)// 定义按钮与对应的图片路径(public 目录下的图片)
const images = [{ id: 'img1', label: '图片1', src: '/image1.png' },{ id: 'img2', label: '图片2', src: '/image2.png' },{ id: 'img3', label: '图片3', src: '/image3.png' },{ id: 'img4', label: '图片4', src: '/image4.png' }
]
</script><style scoped>
.button-group {display: flex;gap: 10px;margin-bottom: 20px;
}
button {padding: 8px 12px;cursor: pointer;
}
.image-container {text-align: center;
}
img {max-width: 100%;height: auto;
}
</style>

截图如下:

在这里插入图片描述

2. 升级Demo

这一版本有个缺点,就是卡顿,但是他的样式很好看!

  • 图片加载问题:每次点击都会重新加载图片,导致延迟
  • 样式导致的渲染卡顿:box-shadow、border 变化可能导致重绘
  • 事件未优化:Vue 响应式 ref 更新时,可能导致不必要的 DOM 计算

更改相关样式以及按钮:

<template><div class="container"><!-- 按钮组 --><div class="button-group"><button v-for="image in images" :key="image.id" @click="currentImage = image.src" class="image-button"><img :src="image.src" alt="Preview" class="button-thumbnail" /><span>{{ image.label }}</span></button></div><!-- 动态展示图片 --><div class="image-container"><img v-if="currentImage" :src="currentImage" alt="Dynamic Image" class="main-image" /></div></div>
</template><script setup>
import { ref } from 'vue'// 当前选中的图片
const currentImage = ref(null)// 定义按钮与对应的图片路径(public 目录下的图片)
const images = [{ id: 'img1', label: '图片1', src: '/favicon.ico' },{ id: 'img2', label: '图片2', src: '/image2.png' },{ id: 'img3', label: '图片3', src: '/image3.png' },{ id: 'img4', label: '图片4', src: '/image4.png' },{ id: 'img5', label: '图片5', src: '/deepSeaField.png' },{ id: 'img6', label: '图片6', src: '/image2.png' },{ id: 'img7', label: '图片7', src: '/image3.png' },{ id: 'img8', label: '图片8', src: '/image4.png' }
]
</script><style scoped>
/* 整体容器 */
.container {max-width: 800px;margin: 0 auto;text-align: center;
}/* 按钮组:使用网格布局 */
.button-group {display: grid;grid-template-columns: repeat(4, 1fr); /* 4 列布局 */gap: 15px;margin-bottom: 20px;
}/* 按钮样式 */
.image-button {display: flex;flex-direction: column;align-items: center;justify-content: center;background: white;border: 2px solid #ddd;border-radius: 12px;padding: 10px;cursor: pointer;transition: all 0.3s ease-in-out;box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
}.image-button:hover {background: #f0f0f0;transform: scale(1.05);
}/* 按钮里的小缩略图 */
.button-thumbnail {width: 50px;height: 50px;border-radius: 8px;object-fit: cover;margin-bottom: 5px;
}/* 主要图片 */
.image-container {margin-top: 20px;
}.main-image {max-width: 100%;height: auto;border-radius: 10px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
</style>

截图如下:

在这里插入图片描述

后续继续整改优化:

<template><div class="container"><!-- 按钮组 --><div class="button-group"><button v-for="image in images" :key="image.id" @click="currentImage = image.src" class="image-button"><img :src="image.src" alt="Preview" class="button-thumbnail" /><span>{{ image.label }}</span></button></div><!-- 动态展示图片 --><div class="image-container"><img v-if="currentImage" :src="currentImage" alt="Dynamic Image" class="main-image" /></div></div>
</template><script setup>
import { ref } from 'vue'// 当前选中的图片
const currentImage = ref(null)// 定义按钮与对应的图片路径(public 目录下的图片)
const images = [{ id: 'img1', label: '图片1', src: '/favicon.ico' },{ id: 'img2', label: '图片2', src: '/image2.png' },{ id: 'img3', label: '图片3', src: '/image3.png' },{ id: 'img4', label: '图片4', src: '/image4.png' },{ id: 'img5', label: '图片5', src: '/deepSeaField.png' },{ id: 'img6', label: '图片6', src: '/image2.png' },{ id: 'img7', label: '图片7', src: '/image3.png' },{ id: 'img8', label: '图片8', src: '/image4.png' }
]
</script><style scoped>
/* 整体容器 */
.container {max-width: 1000px;margin: 0 auto;text-align: center;
}/* 按钮组:一行排列 */
.button-group {display: flex;justify-content: space-around;gap: 10px;margin-bottom: 20px;flex-wrap: wrap; /* 保证小屏设备时自动换行 */
}/* 按钮样式 */
.image-button {display: flex;flex-direction: column;align-items: center;justify-content: center;background: white;border: 2px solid #ddd;border-radius: 12px;padding: 10px;cursor: pointer;transition: all 0.3s ease-in-out;box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);width: 100px; /* 固定宽度 */height: 120px; /* 固定高度 */
}.image-button:hover {background: #f0f0f0;transform: scale(1.05);
}/* 按钮里的小缩略图 */
.button-thumbnail {width: 50px;height: 50px;border-radius: 8px;object-fit: cover;margin-bottom: 5px;
}/* 主要图片 */
.image-container {margin-top: 20px;display: flex;justify-content: center;align-items: center;height: 600px; /* 固定高度,居中展示大图 */border: 2px solid #ddd;border-radius: 10px;box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}.main-image {max-width: 100%;max-height: 100%; /* 确保图片不会超出容器 */object-fit: contain; /* 保持图片比例 */
}
</style>

截图如下:

在这里插入图片描述

3. 终极Demo

后续发现会很卡顿

优化点

  • 去除黑色边框:
    由于 <button> 在不同浏览器默认会有 outline 选中效果,添加 outline: none 解决
    通过 border: none 避免额外边框影响

  • 流畅过渡动画:
    按钮缩略图 采用 background-image,提高图片加载速度
    主图片切换 采用 Vue Transition 并优化 opacity 过渡,使切换更顺畅

  • 减少卡顿:
    预加载所有图片,防止首次切换时加载延迟
    优化 changeImage 逻辑,避免重复更新 currentImage

<template><div class="container"><!-- 按钮组 --><div class="button-group"><buttonv-for="image in images":key="image.id"@click="changeImage(image.src)"class="image-button":class="{ active: currentImage === image.src }"><div class="button-thumbnail" :style="{ backgroundImage: `url(${image.src})` }"></div><span>{{ image.label }}</span></button></div><!-- 动态展示图片 --><div class="image-container"><transition name="fade" mode="out-in"><img v-if="currentImage" :src="currentImage" alt="Dynamic Image" class="main-image" /></transition></div></div>
</template><script setup>
import { ref, onMounted } from 'vue'// 定义按钮与对应的图片路径
const images = [{ id: 'img1', label: '未来制造', src: '/futureManufacturing.png' },{ id: 'img2', label: '未来材料', src: '/futureMaterials.png' },{ id: 'img3', label: '未来信息', src: '/futureInformation.png' },{ id: 'img4', label: '未来能源', src: '/futureEnergy.png' },{ id: 'img5', label: '未来医疗', src: '/futureMedical.png' },{ id: 'img6', label: '人工智能', src: '/artificialIntelligence.png' },{ id: 'img7', label: '数字经济', src: '/digitalEconomy.png' },{ id: 'img8', label: '低空经济', src: '/lowAltitudeEconomy.png' },{ id: 'img9', label: '深海领域', src: '/deepSeaField.png' }
]// 默认选中第一张图片
const currentImage = ref(images[0].src)// 切换图片
const changeImage = (src) => {if (currentImage.value !== src) {currentImage.value = src}
}// 预加载图片,减少切换时的卡顿
const preloadImages = () => {images.forEach(image => {const img = new Image()img.src = image.src})
}onMounted(preloadImages)
</script><style scoped>
/* 整体容器 */
.container {max-width: 1200px;margin: 0 auto;text-align: center;
}/* 按钮组 */
.button-group {display: flex;justify-content: center;gap: 10px;flex-wrap: nowrap;overflow-x: auto;padding: 10px 0;scrollbar-width: none; /* 隐藏滚动条 */
}/* 按钮样式 */
.image-button {display: flex;flex-direction: column;align-items: center;justify-content: center;background: white;border: none;border-radius: 10px;padding: 5px;cursor: pointer;transition: transform 0.2s ease, background 0.2s ease;width: 90px;height: 110px;outline: none; /* 去除点击时的黑框 */
}.image-button:hover {transform: scale(1.05);
}/* 选中状态 */
.image-button.active {background: #e3f2fd;box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}/* 按钮里的小缩略图 */
.button-thumbnail {width: 50px;height: 50px;border-radius: 8px;background-size: cover;background-position: center;margin-bottom: 5px;
}/* 主要图片 */
.image-container {will-change: transform, opacity;margin-top: 10px;display: flex;justify-content: center;align-items: center;height: 600px;border-radius: 10px;width: 100%; /* 增加宽度 */max-width: 1200px; /* 限制最大宽度,防止过大 */box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);overflow: hidden;
}.main-image {max-width: 100%;max-height: 100%;object-fit: contain;
}/* 过渡动画 */
.fade-enter-active, .fade-leave-active {transition: opacity 0.3s ease-in-out;
}
.fade-enter, .fade-leave-to {opacity: 0;
}
</style>

相关文章:

Vue 3:基于按钮切换动态图片展示(附Demo)

目录 前言1. Demo2. 升级Demo3. 终极Demo 前言 原先写过类似的知识点&#xff1a; 详细分析el-breadcrumb 面包屑的基本知识&#xff08;附Demo&#xff09;详细分析el-card中的基本知识&#xff08;附Demo&#xff09; 本篇博客将介绍如何通过点击按钮切换不同的图片&#…...

【Java】泛型与集合篇 —— 泛型

目录 泛型泛型的核心作用泛型类型(类)定义与使用类型参数命名约定泛型方法定义与调用与泛型类的区别通配符上界通配符下界通配符有界类型参数类型擦除类型擦除过程影响好处泛型 泛型的核心作用 泛型是 Java 实现代码复用和类型安全的重要机制。它允许在类、接口和方法中定义…...

【JAVA:list中再定义一个list对象,循环赋值不同的list数据,出现追加重复数据问题】

问题描述&#xff1a; list中再定义一个list对象&#xff0c;循环赋值不同的list数据&#xff0c;结果全部都累加到每条数据中了&#xff0c;每条数据中都出现重复数据。 问题解决&#xff1a; 1.创建树结构方法信息 2.创建一个新的 List 对象&#xff0c;避免引用问题 3.使…...

为什么外贸办公需要跨境专线网络?

你好&#xff0c;今天我们来聊聊SD-WAN技术在出海企业办公中的应用以及其带来的诸多优势。当今出海企业在与海外分支机构或合作伙伴开展高效的网络通讯和数据传输时&#xff0c;面临着许多挑战。此时&#xff0c;SD-WAN作为一种新兴的网络优化技术&#xff0c;正在改变这些企业…...

帆软报表FineReport入门:简单报表制作[扩展|左父格|上父格]

FineReport帮助文档 - 全面的报表使用教程和学习资料 数据库连接 点击号>>JDBC 选择要连接的数据库>>填写信息>>点击测试连接 数据库SQLite是帆软的内置数据库, 里面有练习数据 选择此数据库后,点击测试连接即可 数据库查询 方法一: 在左下角的模板数据集…...

Nginx 在Linux中安装、使用

Nginx 在Linux中安装、使用 一、官网下载Nginx 官网地址&#xff1a;http://nginx.org/en/download.html 二、上传到服务器解压 1、上传到指定的服务器地址 上传的地址自己决定&#xff0c;我上传到 /data/home/prod/nginx/ 2、解压 使用命令&#xff1a; tar -zxvf “你的N…...

在Vue项目中使用three.js在前端页面展示PLY文件或STL文件

前言&#xff1a;这是一个3d打印局域网管理系统的需求 一、安装three.js three.js官网&#xff1a;https://threejs.org/docs/#manual/en/introduction/Installation 我用的是yarn,官网用的是npm 二、使用three.js 1.在script部分导入three.js import * as THREE from thr…...

DeepSeek笔记(二):DeepSeek局域网访问

如果有多台电脑&#xff0c;可以通过远程访问&#xff0c;实现在局域网环境下多台电脑共享使用DeepSeek模型。在本笔记中&#xff0c;首先介绍设置局域网多台电脑访问DeepSeek-R1模型。 一、启动Ollama局域网访问 1.配置环境变量 此处本人的操作系统是Windows11&#xff0c;…...

【LeetCode Hot100 矩阵】矩阵置零、螺旋矩阵、旋转图像、搜索二维矩阵II

矩阵 1. 矩阵置零&#xff08;Set Matrix Zeroes&#xff09;解题思路步骤&#xff1a; 代码实现 2. 螺旋矩阵&#xff08;Spiral Matrix&#xff09;解题思路具体步骤&#xff1a; 代码实现 3. 旋转矩阵 90 度解决思路代码实现 5. 搜索二维矩阵中的目标值解决思路代码实现 1. …...

【设计模式】【创建型模式】建造者模式(Builder)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…...

如何利用国内镜像从huggingface上下载项目

1、利用镜像快速下载项目 在huggingface上下载模型时速度太慢&#xff0c;可以用下面的方法 pip install -U huggingface_hub pip install huggingface-cliexport HF_ENDPOINThttps://hf-mirror.comhuggingface-cli download --resume-download shenzhi-wang/Llama3-8B-Chine…...

pandas常用操作

pandas是Python中用于数据操作和分析的强大库。以下是一些常用的操作&#xff1a; ### 1. 读取数据 - **从CSV文件读取**&#xff1a; python import pandas as pd df pd.read_csv(path/to/file.csv) - **从Excel文件读取**&#xff1a; python df pd.read_exc…...

linux使用

文章目录 前言操作系统的作用组成二、安装linux系统安装VMware Workstation安装ubuntu图形化&#xff0c;命令行finalshell快照目录理解命令执行命令格式常用命令lscdmkdir 前言 本文讲解认识与使用linux操作系统 操作系统的作用 操作系统是用户和计算机的桥梁。比如我们输入…...

基于豆瓣2025电影数据可视化分析系统的设计与实现

✔️本项目旨在通过对豆瓣电影数据进行综合分析与可视化展示&#xff0c;构建一个基于Python的大数据可视化系统。通过数据爬取收集、清洗、分析豆瓣电影数据&#xff0c;我们提供了一个全面的电影信息平台&#xff0c;为用户提供深入了解电影产业趋势、影片评价与演员表现的工…...

基于Python的深度学习音乐推荐系统(有配套论文)

音乐推荐系统 提供实时音乐推荐功能&#xff0c;根据用户行为和偏好动态调整推荐内容 Python、Django、深度学习、卷积神经网络 、算法 数据库&#xff1a;MySQL 系统包含角色&#xff1a;管理员、用户 管理员功能&#xff1a;用户管理、系统设置、音乐管理、音乐推荐管理、系…...

远程计算机无conda情况下配置python虚拟环境

1. 按照正常流程&#xff0c;根据远程计算机的IP地址/用户名/密码&#xff0c;通过pycharm进行部署 部署流程为: pycharm主菜单--> 工具-->部署 -->配置 **注意&#xff0c;pycharm的远程部署必须是专业版 2. 配置远程python解释器 上图是配置SSH解释器的截图&…...

强化学习-价值学习算法

Sarsa 理论解释 Sarsa是基于时序差分算法的&#xff0c;它的公式非常简单且易理解&#xff0c;不像策略梯度算法那样需要复杂的推导过程。 Sarsa的核心函数是 Q ( s , a ) Q(s, a) Q(s,a)&#xff0c;它的含义是在状态 s s s下执行 a a a&#xff0c;在后续轨迹中获取的期望…...

Golang深度学习

前言 在2009年&#xff0c;Google公司发布了一种新的编程语言&#xff0c;名为Go&#xff08;或称为Golang&#xff09;&#xff0c;旨在提高编程效率、简化并发编程&#xff0c;并提供强大的标准库支持。Go语言的设计者们希望通过Go语言能够解决软件开发中的一些长期存在的问…...

基于推荐算法的在线课程推荐系统设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

es和kibana安装

es安装 安装 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.17.1-linux-x86_64.tar.gz 参考&#xff1a; https://www.cnblogs.com/shamo89/p/18504053 https://blog.csdn.net/u012899618/article/details/130383429 解压 tar -zxvf elastic…...

2026年小程序商城如何上线

2026年小程序商城如何上线 小程序商城上线主要涉及三个阶段&#xff1a;平台注册与认证、功能配置与内容填充、提交审核与发布。整个上线周期从3天到3个月不等&#xff0c;SaaS平台方案可在5-14天内完成上线&#xff0c;是当前中小企业最常用的路径。根据微信官方数据&#xff…...

别再只用折线图了!用Matplotlib的fill_between给你的数据加上‘可信度阴影’(Python实战)

用Matplotlib的fill_between为数据可视化注入专业灵魂 当我们在数据分析报告中展示一条平滑的折线时&#xff0c;往往隐藏了一个关键问题&#xff1a;这些数据点背后的不确定性在哪里&#xff1f;传统折线图就像在黑暗中打着手电筒——只能照亮一条狭窄的路径&#xff0c;却忽略…...

ARM浮动许可证管理实战与优化指南

1. ARM浮动许可证管理基础与核心概念在嵌入式开发领域&#xff0c;ARM工具链的许可证管理是每个技术团队必须掌握的技能。作为从业十余年的嵌入式系统架构师&#xff0c;我处理过各种复杂的许可证配置场景&#xff0c;今天将系统性地分享ARM浮动许可证服务器的实战经验。浮动许…...

Proxmox VE模板制作实战:将Ubuntu 22.04 Cloud-Init镜像打造成你的“黄金镜像”

Proxmox VE黄金镜像实战&#xff1a;从Ubuntu 22.04 Cloud-Init到企业级模板的深度优化 在虚拟化环境中&#xff0c;标准化镜像的管理效率直接决定了运维团队的生产力水平。想象一下这样的场景&#xff1a;凌晨三点收到业务扩容需求&#xff0c;你需要快速部署20台配置一致的Ub…...

3D高斯泼溅与AniX框架:实时渲染与视频生成技术解析

1. 3D高斯泼溅技术基础解析3D高斯泼溅&#xff08;3D Gaussian Splatting&#xff0c;简称3DGS&#xff09;是近年来计算机图形学领域的突破性技术&#xff0c;它彻底改变了传统三维场景的表示和渲染方式。这项技术的核心在于将三维空间离散化为数百万个可优化的高斯分布集合&a…...

终极指南:Vue3 + TypeScript 项目如何完美集成 Select2 下拉框

终极指南&#xff1a;Vue3 TypeScript 项目如何完美集成 Select2 下拉框 【免费下载链接】select2 Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results. 项目地址: https://gitcode.com…...

LLM预训练优化:序列打包与掩码注意力技术解析

1. 项目概述&#xff1a;高效LLM预训练的核心挑战在自然语言处理领域&#xff0c;大型语言模型(LLM)的预训练过程往往面临两大核心挑战&#xff1a;计算资源消耗和内存使用效率。传统序列处理方式存在显著的填充(padding)浪费&#xff0c;而标准的注意力机制在长序列处理时会产…...

开源免费的WPS AI 软件 察元AI文档助手:链路 007:getConfiguredAssistantModelId 与分类默认模型

链路 007&#xff1a;getConfiguredAssistantModelId 与分类默认模型 总体链路图 下图在全系列各篇保持一致&#xff0c;仅通过高亮样式标示本篇所覆盖的环节&#xff1b;箭头表示主成功路径&#xff0c;点线为异常或可选路径。阅读任意一篇时都应能回到本图定位&#xff0c;…...

nli-MiniLM2-L6-H768批量处理优化:利用GPU并行计算加速大规模文本对推理

nli-MiniLM2-L6-H768批量处理优化&#xff1a;利用GPU并行计算加速大规模文本对推理 1. 引言 处理海量文本对&#xff08;如百万级&#xff09;的自然语言推理任务时&#xff0c;传统的单条处理方式效率极低。以nli-MiniLM2-L6-H768模型为例&#xff0c;当面对大规模数据时&a…...

物理AI推动人机协作迈向新阶段研究报告凯捷 2026_01

这份凯捷 2026 年《物理 AI&#xff1a;推动人机协作迈向新阶段》报告核心结论&#xff1a;物理 AI 正让机器人从预编程工具变成可感知、自适应、能学习的现实世界智能合作者&#xff0c;已到规模化拐点&#xff0c;将重构各行业生产力与人机协作模式。一、核心定义&#xff1a…...