<script setup lang=“ts“>+uniapp实现轮播(swiper)效果

效果图1:

代码:

复制代码
<template>
 <view class="carousel-container">
    <!-- 姓名导航栏移至轮播上方 -->
    <view class="name-nav">
        <view
            v-for="(item, index) in personList"
            :key="index"
            :class="{ active: activeIndex === index }"
            @click="activeIndex = index"
        >
            {{ item.name }}
        </view>
    </view>

    <!-- 轮播内容区域 -->
    <swiper class="swiper" :current="activeIndex" :autoplay="true" @change="handleSwiperChange">
        <swiper-item v-for="(item, index) in personList" :key="index">
            <view class="card">
                <image :src="item.avatar" class="avatar" mode="aspectFit" />
                <view class="info">
                    <view class="item">姓名:{{ item.name }}</view>
                    <view class="item">性别:{{ item.gender }}</view>
                    <view class="item">民族:{{ item.nation }}</view>
                    <view class="item">出生:{{ item.birth }}</view>
                    <view class="item">住址:{{ item.address }}</view>
                    <view class="item">身份证号:{{ item.idNo }}</view>
                </view>
                <image :src="item.signature" class="signature" mode="aspectFit" />
            </view>
        </swiper-item>
    </swiper>
</view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 轮播数据列表
const personList = [
    {
        name: '韦小宝',
        gender: '男',
        nation: '汉',
        birth: '1654年12月20日',
        address: '北京市东城区景山前街4号紫禁城敬事房',
        idNo: '110101165412200001',
        avatar: '/static/weixiaobao.png', // 替换为实际头像路径
        signature: '/static/signature1.png', // 替换为实际签名路径
    },
    {
        name: '多隆',
        gender: '男',
        nation: '满',
        birth: '1652年05月10日',
        address: '北京市西城区西单大街5号',
        idNo: '110102165205100002',
        avatar: '/static/duolong.png',
        signature: '/static/signature2.png',
    },
    {
        name: '小双',
        gender: '女',
        nation: '汉',
        birth: '1656年08月15日',
        address: '北京市朝阳区建国路8号',
        idNo: '110105165608150003',
        avatar: '/static/xiaoshuang.png',
        signature: '/static/signature3.png',
    },
];

// 激活的索引
const activeIndex = ref(0);

// 轮播切换时同步索引
const handleSwiperChange = (e: { detail: { current: number } }) => {
  activeIndex.value = e.detail.current;
};
</script>

<style scoped>
.carousel-container {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 15rpx; /* 姓名栏与轮播的间距 */
    padding: 20rpx;
    box-sizing: border-box;
}

/* 姓名导航栏样式(顶部) */
.name-nav {
    display: flex;
    justify-content: center; /* 姓名居中分布 */
    gap: 30rpx; /* 姓名之间的间距 */
    padding: 10rpx 0;
    background-color: #f5f5f5;
    border-radius: 12rpx;
    width: 100%;
    overflow-x: auto; /* 姓名过多时可横向滚动 */
    white-space: nowrap; /* 防止姓名换行 */
}

.name-nav view {
    font-size: 28rpx;
    padding: 5rpx 15rpx; /* 增加点击区域 */
    color: #666;
    position: relative;
    transition: color 0.3s;
}

/* 选中姓名的高亮样式 */
.name-nav view.active {
    color: #007AFF; /* 主题色高亮 */
    font-weight: bold;
}

/* 可选:添加底部指示线增强选中效果 */
.name-nav view.active::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 20rpx;
    height: 4rpx;
    background-color: #007AFF;
    border-radius: 2rpx;
}

/* 轮播区域样式 */
.swiper {
    width: 100%;
    height: 500rpx; /* 轮播高度可根据内容调整 */
    border-radius: 12rpx;
    overflow: hidden;
}

.card {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20rpx;
    background-color: #fff;
    height: 100%;
    box-sizing: border-box;
}

.avatar {
    width: 160rpx;
    height: 160rpx;
    border-radius: 50%;
    margin-bottom: 20rpx;
    border: 2rpx solid #eee;
}

.info {
    width: 100%;
    margin-bottom: 20rpx;
}

.item {
    font-size: 26rpx;
    line-height: 40rpx;
    color: #333;
    padding-left: 10rpx;
}

.signature {
    width: 100%;
    height: 120rpx;
    margin-top: auto; /* 签名区域靠下 */
}
</style>

效果图2:

代码:

复制代码
<template>
  <view class="carousel-container">
    <!-- 轮播内容区域 -->
    <swiper
      class="swiper"
      :current="activeIndex"
      :autoplay="true"
      @change="handleSwiperChange"
    >
      <swiper-item v-for="(item, index) in personList" :key="index">
        <view class="card">
          <image :src="item.avatar" class="avatar" mode="aspectFit" />
          <view class="info">
            <view class="item">姓名:{{ item.name }}</view>
            <view class="item">性别:{{ item.gender }}</view>
            <view class="item">民族:{{ item.nation }}</view>
            <view class="item">出生:{{ item.birth }}</view>
            <view class="item">住址:{{ item.address }}</view>
            <view class="item">身份证号:{{ item.idNo }}</view>
          </view>
         
        </view>
      </swiper-item>
    </swiper>

    <!-- 姓名导航栏(默认展示所有姓名,选中高亮) -->
    <view class="name-nav">
      <view
        v-for="(item, index) in personList"
        :key="index"
        :class="{ active: activeIndex === index }"
        @click="activeIndex = index"
      >
        {{ item.name }}
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 轮播数据列表
const personList = [
  {
    name: '韦小宝',
    gender: '男',
    nation: '汉',
    birth: '1654年12月20日',
    address: '北京市东城区景山前街4号紫禁城敬事房',
    idNo: '110101165412200001',

  },
  {
    name: '多隆',
    gender: '男',
    nation: '满',
    birth: '1652年05月10日',
    address: '北京市西城区西单大街5号',
    idNo: '110102165205100002',
  
  },
  {
    name: '小双',
    gender: '女',
    nation: '汉',
    birth: '1656年08月15日',
    address: '北京市朝阳区建国路8号',
    idNo: '110105165608150003',
  
  },
];

// 激活的索引
const activeIndex = ref(0);

// 轮播切换时同步索引
const handleSwiperChange = (e: { detail: { current: number } }) => {
  activeIndex.value = e.detail.current;
};
</script>

<style scoped>
.carousel-container {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  padding: 20rpx;
}

.swiper {
  width: 100%;
  height: 500rpx;
}

.card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20rpx;
  background-color: #fff;
  border-radius: 12rpx;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}

.avatar {
  width: 200rpx;
  height: 200rpx;
  border-radius: 50%;
  margin-bottom: 10rpx;
}

.info {
  width: 100%;
  margin-bottom: 20rpx;
}

.item {
  font-size: 28rpx;
  line-height: 40rpx;
  margin-bottom: 8rpx;
}

.signature {
  width: 100%;
  height: 150rpx;
}

.name-nav {
  display: flex;
  justify-content: space-around;
  height: 80rpx;
  line-height: 80rpx;
  background-color: #f5f5f5;
  border-radius: 12rpx;
}

.name-nav view {
  font-size: 28rpx;
  cursor: pointer;
}

.name-nav view.active {
  color: #007AFF;
  font-weight: bold;
  border-bottom: 4rpx solid #007AFF;
}
</style>
相关推荐
2501_916008893 小时前
iOS 26 文件导出与数据分析,多工具组合下的开发者实践指南
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_916008893 小时前
iOS混淆实战用多工具组合把IPA加固做成可复用的工程能力(iOS混淆 IPA加固 无源码混淆
android·ios·小程序·https·uni-app·iphone·webview
wangdaoyin20103 小时前
UniApp 在手机端(Android)打开选择文件和文件写入
android·前端·uni-app
用户497357337983 小时前
高端Web全栈工程师精品就业实战班课程 从零打造Web架构师
前端
我们没有完整的家3 小时前
技术速递|Playwright MCP 调试 Web 应用时,GitHub Copilot 生成断言脚本的实用方法
前端·github·copilot
universe_013 小时前
前端学习之八股和算法
前端·学习
一川_3 小时前
ElementUI分页器page-size切换策略:从保持当前页到智能计算的优化实践
前端
敲敲了个代码3 小时前
[特殊字符] Web 字体裁剪优化实践:把 42MB 字体包瘦到 1.6MB
前端·javascript·学习·html·web
change_fate3 小时前
vue3 懒加载第三方组件
javascript·vue.js·ecmascript