UNIAPP块元素滑动组件

前言

近期有个小程序项目,客户需要详情页面展示该项目的图片,并点击图片能修改图片携带的参数,直接点击图片在页面上方或下方都会遇到图片太多,一直上下滑动,不便于操作,于是又以下解决方法:

解决方案

一、直接将图片预览和信息编辑弹窗的方式来解决

优点:不用再要编辑时,上下滑动到指定位置编辑

缺点:每次只能修改一张

二、将整个弹出层的块写成滑块

这样每次滑动到不同的图片,图片的参数也能得到同步展示并修改

下面是我自己写的个组件来完成这个功能,如果您有更好的方法,欢迎讨:

使用教程

一、先在uniapp创建组件(不要问组件怎么创建 ,百度啥都会教你)

要在ImageSliderItem.vue中展示特定imgId对应的图片信息,并实现左右滑动更换数据的功能,你可以按照以下步骤进行修改:

  1. ImageSliderItem.vue组件中,添加一个props属性imgId,用于接收父组件传递的imgId值。
    props: {
      imgId: {
        type: Number,
        required: true
      }
    },
    1. data中定义一个变量currentIndex,用于记录当前展示的图片在数组中的索引位置。
      data() {
        return {
          currentIndex: -1
        };
      },
  1. mounted钩子函数中,根据传递的imgId查找对应的图片在数组中的索引,并将索引值赋给currentIndex
    mounted() {
      this.currentIndex = this.findIndexById(this.imgId);
    },
    methods: {
      findIndexById(imgId) {
        // 假设图片数组为images
        return this.images.findIndex(item => item.imgId === imgId);
      }
    }

     

  2. 在模板中根据currentIndex来展示对应的图片信息。
    <template>
      <div>
        <img :src="images[currentIndex].url" alt="Image">
      </div>
    </template>
  1. 实现左右滑动更换数据的功能,你可以使用touchstarttouchmovetouchend事件来监听用户的滑动操作,并根据滑动的距离和方向来更新currentIndex的值。
    <template>
      <div
        @touchstart="onTouchStart"
        @touchmove="onTouchMove"
        @touchend="onTouchEnd"
      >
        <img :src="images[currentIndex].url" alt="Image">
      </div>
    </template>
    data() {
      return {
        currentIndex: -1,
        touchStartX: 0,
        touchEndX: 0
      };
    },
    methods: {
      onTouchStart(event) {
        this.touchStartX = event.touches[0].clientX;
      },
      onTouchMove(event) {
        this.touchEndX = event.touches[0].clientX;
      },
      onTouchEnd() {
        const threshold = 50; // 滑动切换的阈值
    
        if (this.touchEndX - this.touchStartX > threshold) {
          // 向右滑动
          this.showPreviousImage();
        } else if (this.touchStartX - this.touchEndX > threshold) {
          // 向左滑动
          this.showNextImage();
        }
      },
      showPreviousImage() {
        if (this.currentIndex > 0) {
          this.currentIndex--;
        }
      },
      showNextImage() {
        if (this.currentIndex < this.images.length - 1) {
          this.currentIndex++;
        }
      }
    }

    在上述示例代码中,假设图片数组为images,每个图片对象包含imgIdurl属性。通过监听触摸事件,根据滑动的距离和方向来切换展示的图片。showPreviousImageshowNextImage方法分别用于向前和向后切换图片。

    最后,在Hongpage.vue组件中,将图片数组和选中的imgId传递给ImageSliderItem.vue组件。

    <template>
      <div>
        <!-- 其他内容 -->
        <ImageSliderItem :images="images" :imgId="selectedImgId" />
      </div>
    </template>
    
    <script>
    import ImageSliderItem from './ImageSliderItem.vue';
    
    export default {
      components: {
        ImageSliderItem
      },
      data() {
        return {
          images: [
            { imgId: 1, url: 'xx.png' },
            { imgId: 2, url: 'xx.png' },
            { imgId: 3, url: 'xx.png' },
            { imgId: 4, url: 'xx.png' }
          ],
          selectedImgId: 3
        };
      }
    };
    </script>

    通过将imagesselectedImgId传递给ImageSliderItem组件,实现了根据选中的imgId展示对应的图片,并可以通过左右滑动切换图片的功能。

以下是完整示例代码:

在components下创建ImageSlider文件夹并创建ImageSlider.vue、ImageSliderItem.vue、ImageSliderItemDetail.vue三个文件

ImageSlider.vue:

ImageSliderItem.vue:

ImageSliderItemDetail.vue:(可有可无,看个人项目情况)

<template>
  <view class="image-slider-item-detail">
    <image :src="item.imgAddress" mode="aspectFill" />
    <view class="close" @click="handleClose">关闭</view>
  </view>
</template>

<script>
export default {
	name:"ImageSliderItemDetail",
  props: {
    item: {
      type: Object,
      required: true,
    },
  },
  methods: {
    handleClose() {
      this.$emit('close');
    },
  },
};
</script>

<style scoped>
.image-slider-item-detail {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.8);
}

.image-slider-item-detail image {
  width: 80%;
  height: 80%;
  object-fit: contain;
}

.close {
  margin-top: 20px;
  color: #fff;
  font-size: 16px;
}
</style>

最后你哪儿需要用就在哪儿调用这个组件即可

<template>
  <div class="home-page">
    <u-popup :show="showPopup" mode="top" closeable>
      <image-slider
        :images="images"
        :currentIndex="currentIndex"
        @change="handleChange"
      />
    </u-popup>
    <div class="image-list">
      <div
        class="image-item"
        v-for="(item, index) in images"
        :key="item.imgId"
        @click="handleItemClick(index)"
      >
        <img :src="item.imgAddress" />
      </div>
    </div>
  </div>
</template>

<script>
import ImageSlider from '@/components/ImageSlider/ImageSlider.vue';

export default {
  components: {
    ImageSlider,
  },
  data() {
    return {
      showPopup: false,
      currentIndex: 0,
      images: [
        {
          imgId: "1",
          imgAddress: "https://www.oove.cn/wp-content/uploads/2023/08/4e69780498133508.png",
          uploadTime: "2023-08-30 16:20:21",
        },
        {
          imgId: "2",
          imgAddress: "https://huijl.oss-cn-shanghai.aliyuncs.com/7443967946455794588.jpg",
          uploadTime: "2023-08-30 16:20:21",
        },
        {
          imgId: "3",
          imgAddress: "https://www.oove.cn/wp-content/uploads/2023/08/f85f4b6ea2133507.png",
          uploadTime: "2023-08-30 16:20:21",
        },
        // 其他图片数据...
      ],
    };
  },
  methods: {
    handleItemClick(index) {
      this.currentIndex = index;
      this.showPopup = true;
    },
    handleChange(index) {
      this.currentIndex = index;
    },
  },
};
</script>

<style scoped>
.home-page {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.image-list {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 20px;
}

.image-item {
  margin: 0 10px;
  cursor: pointer;
}

.image-item img {
  width: 100px;
  height: 100px;
}
</style>

 

说明

  • 欢迎技术交流讨论,也希望大家常来程序猿作客!还有什么不懂的可联系站长或在下方留言。
  • 本教程由【程序猿】原创首发,未经允许请勿转载,谢谢合作!

结语:样式没写完,自己写,记录每一个技术问题!

欢迎加入程序猿大家庭(QQ群)~~~

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容