【微信小程序】仿小红书轮播图

629 阅读2分钟

小红书是一款受欢迎的生活方式分享平台,用户可以通过分享图片和视频记录生活点滴。本文将基于uniapp(vue@3.4.21(typescript@4.9.5))的微信小程序开发,实现类似查看图片轮播的体验,并分享一些开发中的关键点和注意事项。

​编辑

需求分析

通过对小红书微信小程序的轮播图分析,可得出以下总结:

  • 单张图片时容器根据图片像素定高
  • 多图时轮播图容器高度以首图为锚点
  • 比首图长则固高左右留白
  • 比首图短则固宽上下留白

实现步骤

  • 模板编写

<lo-nav ref="navRef" :config="nvConfig" />
<view class="page" :style="{ height: `calc(100vh - ${navHeight}px ) ` }">
   <!-- 轮播图 -->
   <view class="page-swiper" :class="`h-${swiperHeight || '503px'}`">
     <wd-swiper
       v-if="imageList.length"
       :list="imageList"
       :indicator="{ type: 'dots-bar' }"
       :height="swiperHeight"
       :autoplay="false"
       imageMode="aspectFit"
       v-model:current="current"
       @click="handlePreview"
       @change="handleChange"
     ></wd-swiper>
   </view>
</view>

  • script代码实现

在调后端接口获取数据之后,通过封装的getImgHeight方法区获取首图的图片高度,从而确定轮播图容器的高度。

/** 轮播 swiper 高度 */
const swiperHeight = ref('503px')
/** 当前轮播 */
const current = ref<number>(0)
/** 图片列表 */
const imageList = ref([])
/** 轮播点击预览图片 */
const handlePreview = () => {
  uni.previewImage({
    current: current.value,
    urls: imageList.value,
  })
}
/** 轮播图切换变化 */
const handleChange = (swiper) => {
  current.value = swiper.current
}

/** 数据id */
let id: undefined | number
/** 获取详情数据 */
const getDetail = () => {
  getInformationDetail({ id }).then((res) => {
    imageList.value = res.data.fileList || []
    const firstImg = imageList.value[0] || ''
    getImgHeight(firstImg).then((heightRes) => {
      swiperHeight.value = heightRes
    })
  })
}

 getImgHeight方法:函数的主要目的是根据图片的宽高比和设备屏幕宽度来计算适合的图片容器高度,并且确保图片不会超过最大高度 503px

/**
 * 计算图片容器高度
 * @param {string} imageUrl -- 图片路径
 */
export const getImgHeight = (imageUrl: string) => {
  let containerHeight = '503px'
  return new Promise<string>((resolve, reject) => {
    wx.getImageInfo({
      src: imageUrl,
      success: (res) => {
        const { width, height } = res
        uni.getSystemInfo({
          success: (res) => {
            const screenWidth = res.windowWidth
            const aspectRatio = width / height
            const imgHeight = screenWidth / aspectRatio
            containerHeight = `${imgHeight && imgHeight < 503 ? imgHeight : 503}px`
            resolve(containerHeight)
          },
        })
      },
      fail: (err) => {
        console.error('Failed to get image info', err)
        reject(containerHeight)
      },
    })
  })
}

  • CSS样式

.page {
  overflow: auto;
  --wot-swiper-nav-dot-color: rgba(255, 255, 255, 0.6);
  --wot-swiper-nav-dot-active-color: #4d80f0;
  --wot-swiper-radius: 0;

  &-swiper {
    position: relative;
    width: 100%;
    max-height: 503px;
  }
}

实现效果

单张图片:

​编辑

长图-短图-长图:

​编辑

短图-长图-短图:

​编辑

注意细节

  • 当图片较大时,轮播图切换有可能会出现卡壳的情况,因此需要用v-model:current绑定一下当前图片索引,监听change事件再重新赋值。
  • 若图片较大,可以考虑加载缩略图,点击图片预览时再加载原图。

以上就是微信小程序仿小红书轮播图的实现啦^-^