Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Hooke
/
hager
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
hookehuyr
2024-09-27 20:36:28 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
2b87ffb52203e51f5e557182d7ee7866734d8176
2b87ffb5
1 parent
8c539306
✨ feat: 新增详情页产品显示切换组件测试
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
201 additions
and
4 deletions
components.d.ts
src/components/hagerCarousel.vue
src/views/index.vue
components.d.ts
View file @
2b87ffb
...
...
@@ -18,12 +18,14 @@ declare module 'vue' {
ElInput
:
typeof
import
(
'element-ui/lib/input'
)[
'default'
]
ElRow
:
typeof
import
(
'element-ui/lib/row'
)[
'default'
]
HagerBox
:
typeof
import
(
'./src/components/common/hagerBox.vue'
)[
'default'
]
HagerCarousel
:
typeof
import
(
'./src/components/hagerCarousel.vue'
)[
'default'
]
HagerFooter
:
typeof
import
(
'./src/components/common/hagerFooter.vue'
)[
'default'
]
HagerHeader
:
typeof
import
(
'./src/components/common/hagerHeader.vue'
)[
'default'
]
Navbar
:
typeof
import
(
'./src/components/navbar.vue'
)[
'default'
]
RouterLink
:
typeof
import
(
'vue-router'
)[
'RouterLink'
]
RouterView
:
typeof
import
(
'vue-router'
)[
'RouterView'
]
SlideComp
:
typeof
import
(
'./src/components/slideComp.vue'
)[
'default'
]
TagerCarousel
:
typeof
import
(
'./src/components/tagerCarousel.vue'
)[
'default'
]
VideoPlayer
:
typeof
import
(
'./src/components/videoPlayer.vue'
)[
'default'
]
}
}
...
...
src/components/hagerCarousel.vue
0 → 100644
View file @
2b87ffb
<!--
* @Date: 2024-09-27 19:49:03
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-27 20:09:22
* @FilePath: /hager/src/components/hagerCarousel.vue
* @Description: 文件描述
-->
<template>
<div class="hager-carousel">
<div class="image-switcher">
<!-- 缩略图区域 -->
<div class="thumbnail-container">
<!-- 上箭头 -->
<div class="arrow-up" @click="prevImage">▲</div>
<!-- 缩略图列表 -->
<div class="thumbnails">
<div
v-for="(image, index) in visibleThumbnails"
:key="index"
:class="['thumbnail', { active: selectedImage === (startIndex + index) }]"
@click="selectImage(startIndex + index)"
>
<img :src="image" alt="thumbnail">
</div>
</div>
<!-- 下箭头 -->
<div class="arrow-down" @click="nextImage">▼</div>
</div>
<!-- 右边大图区域 -->
<div class="main-image" :class="{ 'fade-out': isTransitioning, 'fade-in': !isTransitioning }">
<img :src="images[selectedImage]" alt="main image">
</div>
</div>
</div>
</template>
<script>
import mixin from "common/mixin";
export default {
mixins: [mixin.init],
data() {
return {
selectedImage: 0, // 当前选中的图片索引
startIndex: 0, // 当前显示的缩略图起始索引
thumbnailsToShow: 4, // 每次显示4个缩略图
isTransitioning: false, // 控制大图的切换动画
images: [
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
"https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
"https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
"https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg",
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
],
};
},
mounted() {},
computed: {
// 计算当前显示的缩略图
visibleThumbnails() {
return this.images.slice(this.startIndex, this.startIndex + this.thumbnailsToShow);
},
endIndex() {
return this.startIndex + this.thumbnailsToShow - 1;
}
},
methods: {
// 选择某个图片并更新大图和选中状态
selectImage(index) {
this.isTransitioning = true; // 开始大图的淡出动画
setTimeout(() => {
this.selectedImage = index; // 切换大图
this.isTransitioning = false; // 动画结束
this.ensureVisibleThumbnail(); // 保证选中的缩略图在可视区域
}, 500); // 动画时间为500ms
},
// 控制缩略图上下滚动
scrollThumbnails(direction) {
if (direction === 'up' && this.startIndex > 0) {
this.startIndex--;
} else if (direction === 'down' && this.endIndex < this.images.length - 1) {
this.startIndex++;
}
},
// 确保选中的缩略图在可见范围内
ensureVisibleThumbnail() {
if (this.selectedImage < this.startIndex) {
// 如果选中的缩略图在当前显示范围的上方,则向上滚动
this.startIndex = this.selectedImage;
} else if (this.selectedImage > this.endIndex) {
// 如果选中的缩略图在当前显示范围的下方,则向下滚动
this.startIndex = this.selectedImage - this.thumbnailsToShow + 1;
}
},
// 切换到下一张图片
nextImage() {
if (this.selectedImage < this.images.length - 1) {
this.selectImage(this.selectedImage + 1);
}
},
// 切换到上一张图片
prevImage() {
if (this.selectedImage > 0) {
this.selectImage(this.selectedImage - 1);
}
}
},
};
</script>
<style lang="less" scoped>
.hager-carousel {
.image-switcher {
display: flex;
align-items: center;
}
.thumbnail-container {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 20px;
}
.arrow-up,
.arrow-down {
cursor: pointer;
padding: 5px;
font-size: 18px;
user-select: none;
}
.thumbnails {
display: flex;
flex-direction: column;
align-items: center;
max-height: 220px; /* 限制缩略图容器的高度 */
overflow: hidden;
position: relative; /* 为缩略图滚动效果提供基础 */
}
.thumbnail {
width: 50px;
height: 50px;
margin-bottom: 10px;
cursor: pointer;
border: 2px solid transparent;
transition: border 0.3s;
}
.thumbnail img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease-in-out; /* 缩略图切换时的动画效果 */
}
.thumbnail.active {
border: 2px solid #00f; /* 选中的缩略图边框样式 */
}
.main-image {
width: 300px;
height: 300px;
position: relative;
transition: opacity 0.5s ease-in-out; /* 大图切换时的淡入淡出效果 */
opacity: 1;
}
.main-image img {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
}
.main-image.fade-out {
opacity: 0; /* 当切换时,将大图的透明度渐变为0 */
}
.main-image.fade-in {
opacity: 1; /* 切换后,图片渐渐显现 */
}
.thumbnails-wrapper {
transition: transform 0.5s ease-in-out; /* 缩略图滑动时的动画效果 */
display: flex;
flex-direction: column;
}
}
</style>
src/views/index.vue
View file @
2b87ffb
<!--
* @Date: 2024-08-27 10:06:30
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-2
6 17:18:46
* @LastEditTime: 2024-09-2
7 19:51:44
* @FilePath: /hager/src/views/index.vue
* @Description: 文件描述
-->
<template>
<div>
<hager-box style="background-color: #fff;">
<div v-for="(item, index) in 10" :key="index">
<div style="height: 5rem;">{{ index + 1 }}</div>
</div>
<hager-carousel></hager-carousel>
</hager-box>
<hager-box style="background-color: #f1f1f1;">
<div v-for="(item, index) in 10" :key="index">
...
...
@@ -23,6 +21,7 @@
<script>
import mixin from '@/common/mixin';
import hagerBox from '@/components/common/hagerBox';
import hagerCarousel from '@/components/hagerCarousel';
export default {
mixins: [mixin.init],
...
...
Please
register
or
login
to post a comment