uniapp 基于Vue的动态标签页与滑动切换实现

619 阅读3分钟

创建基本结构

首先,在模板部分(.vue文件的标签内),我们将定义整个组件的基本结构。这里包括一个用于显示标签列表的scroll-view和一个用于展示内容区域的swiper组件。

<template>
  <view class="container">
    <scroll-view scroll-y>
      <view class="tab-list">
        <view
          class="tab-item"
          v-for="(item, index) in tabList"
          :key="index"
          :class="currentIndex==index ? 'activeTab' : ''"
          @click="changeTab(index)"
        >
          {{ item.name }}
        </view>
      </view>
    </scroll-view>
    <swiper class="swiper" :current="currentIndex" @change="handleSwiperChange">
      <swiper-item v-for="(tab, index) in goodList" :key="index">
        <view class="swiper-item" :style="{backgroundColor: tab.bgColor}">
          <view class="tab">
            <image :src="tab.icon" mode="aspectFit"></image>
            <text>{{ tab.name }}</text>
          </view>
        </view>
      </swiper-item>
    </swiper>
  </view>
</template>

在这个结构中,我们使用了两个核心组件: scroll-view: 用于包裹标签列表,使其可以在垂直方向上滚动。 swiper: 包含多个swiper-item子组件,每个子组件代表一个独立的内容区域。

数据绑定与事件处理

接下来,我们需要在脚本部分(.vue文件的script标签内)初始化一些数据,并定义相关的事件处理函数。

<script>
  export default {
    data() {
      return {
        currentIndex: 0,
        goodList: [
          {
            name: "购物",
            icon: "/static/images/shopping.png",
            bgColor: "#1e80ff",
          },
          {
            name: "购物篮",
            icon: "/static/images/cart.png",
            bgColor: "#86909c",
          },
        ],
        shoppingList: ["商品1", "商品2", "商品3", "商品4"],
        cartList: ["已添加商品1", "已添加商品2", "已添加商品3"],
        tabList: [
          { id: 112, name: "待付款" },
          { id: 113, name: "已付款" },
        ],
      };
    },
    methods: {
      handleSwiperChange(event) {
        this.currentIndex = event.detail.current;
      },
      changeTab(key) {
        console.log(key, "================");
        this.currentIndex = key;
      },
    },
  };
</script>

定义了一个名为currentIndex的数据属性,用来记录当前激活的标签页索引。 在goodList数组中存储了每个标签页的具体信息,如名称、图标路径和背景颜色。 编写了两个方法:handleSwiperChange用于监听swiper组件的变化事件,并更新currentIndex; changeTab则是在点击某个标签时触发,同样会更新currentIndex。

样式美化

最后一步是对整个组件进行样式上的优化。为了使UI更加美观和谐,我们在样式部分(.vue文件的标签内)添加了一些必要的CSS规则。

   <style lang="scss"scoped>.activeTab {
  color: #333;
  border-bottom: 2px solid #d73b3b;
}

.tab-list {
  display: flex;
  width: 100%;
  color: #878789;
  padding: 30rpx;

  .tab-item {
    margin-right: 30rpx;
    padding-bottom: 20rpx;
  }
}

.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.swiper {
  height: 300px;

  .swiper-item {
    display: flex;
    justify-content: center;
    align-items: center;

    .tab {
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 10px 20px;
      text-align: center;

      image {
        width: 30px;
        height: 30px;
      }

      text {
        display: block;
        font-size: 16px;
      }
    }
  }
}

.content-scroll-view {
  // flex: 1; padding: 20px; background-color: #fff; .list { text { display: block; margin: 10px 0; font-size: 18px; } } }
  </style>

以下是全部代码

<template>
  <view class="container">
    <!-- Swiper 用于切换标签页 -->
	<!-- Scroll-view 用于内容区域的滚动 -->
	<scroll-view scroll-y>
	  <view class="tab-list">
	  	<view class="tab-item" v-for="(item, index) in tabList" :key="index" :class="currentIndex==index ? 'activeTab' : ''" @click="changeTab(index)">
	  		{{ item.name }}
	  	</view>
	  </view>
	</scroll-view>
    <swiper class="swiper" :current="currentIndex" @change="handleSwiperChange">
      <swiper-item v-for="(tab, index) in goodList" :key="index">
		  
        <view class="swiper-item" :style="{backgroundColor: tab.bgColor}">
          <view class="tab">
            <image :src="tab.icon" mode="aspectFit"></image>
            <text>{{ tab.name }}</text>
          </view>
        </view>
      </swiper-item>
    </swiper>

    
  </view>
</template>

<script>
export default {
  data() {
    return {
      currentIndex: 0,
      goodList: [
        { name: '购物', icon: '/static/images/shopping.png', bgColor: '#1e80ff' },
        { name: '购物篮', icon: '/static/images/cart.png', bgColor: '#86909c' }
      ],
      shoppingList: ['商品1', '商品2', '商品3', '商品4'],
      cartList: ['已添加商品1', '已添加商品2', '已添加商品3'],
	  tabList: [
		  { id: 112, name: '待付款' },
		  { id: 113, name: '已付款' }
	  ]
    };
  },
  methods: {
    handleSwiperChange(event) {
      this.currentIndex = event.detail.current;
    },
	changeTab(key){
		console.log(key, '================');
		this.currentIndex = key
	}
  }
};
</script>

<style lang="scss" scoped>
	.activeTab{
		color: #333;
		border-bottom: 2px solid #d73b3b;
	}
	.tab-list{
		display: flex;
		width: 100%;
		color: #878789;
		padding: 30rpx;
		.tab-item{
			margin-right: 30rpx;
			padding-bottom: 20rpx;
		}
	}
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.swiper {
  height: 300px;
  .swiper-item {
    display: flex;
    justify-content: center;
    align-items: center;
    .tab {
      display: flex;
      flex-direction: column;
      align-items: center;
      padding: 10px 20px;
      text-align: center;
      image {
        width: 30px;
        height: 30px;
      }
      text {
        display: block;
        font-size: 16px;
      }
    }
  }
}

.content-scroll-view {
  // flex: 1;
  padding: 20px;
  background-color: #fff;
  .list {
    text {
      display: block;
      margin: 10px 0;
      font-size: 18px;
    }
  }
}
</style>