封装轮播图 (因为基于微博小程序,语法可能有些出入,如需使用需改标签)

这是在组件中使用,基于微博语法

javascript 复制代码
<template>
  <wbx-view class="" style="width: 100vw;height: 70vh;">
    <WBXswiper @change="gaibian" :vertical="false" :current="current" indicatorActiveColor="#fff" indicatorColor="#c0c0c0" :items="items"   style="width: 375px;height: 200px;border-radius: 20px;">
       <template slot="swiperItem" slot-scope="scope">
			    <wbx-image :src="scope.item.src" mode="aspectFill" style="width:375px; height: 200px;" />
       </template>
     </WBXswiper>
     <!-- //测试点击切换轮播 -->
     <wbx-view  style="margin-bottom: 30px;">
        <web-view style="width: 30px;height: 30px;border: 1px solid red;" @click="add(0)">
          <view-text>0</view-text>
        </web-view>
        <web-view style="width: 30px;height: 30px;border: 1px solid red;" @click="add(1)">
          <view-text>1</view-text>
        </web-view>
        <web-view style="width: 30px;height: 30px;border: 1px solid red;" @click="add(2)">
          <view-text>2</view-text>
        </web-view>
    </wbx-view>
	</wbx-view>
</template>

<script>
/**
 * @type WBXAppOption
 */
import WBXswiper from "../../commpents/WBXswiper/index.vue";
const pageOptions = {
  data() {
    return {
      items: [
      	{ 
      	  src: 'res/1.jpg',
          txt:222222
		},
		{ 
      	  src: 'res/1.jpg',
          txt:222222
		},
		{ 
      	  src: 'res/1.jpg',
          txt:222222
		},
	 ],
      current:0
	}
  },
  computed:{
  },
  methods: {
    gaibian(e){
      console.log(e,'change')
    },
    add(index){
      console.log(this.current)
      this.current=index
    }
  },
  components: {
    WBXswiper,
  },
  wbox: {
    onLoad() { },
    onShow() {
      // 页面显示/切入前台时触发
    },
    onHide() {
      // 页面隐藏时触发
    },
    onUnload() {
      // 页面退出时触发
    },
  },
  mounted() { },
};
export default pageOptions;
</script>

<style></style>

自己封装的swiper组件内部

javascript 复制代码
<template>
    <wbx-view
      ref="objStyle"
      :style="wrapperStyle"
      @touchstart="onTouchStart"
      @touchmove="onTouchMove"
      @touchend="onTouchEnd"
    >
      <wbx-view
        class="carousel-wrapper"
        :style="carouselStyle"
        @transitionend="onTransitionEnd"
        ref="carouselWrapper"
      >
        <wbx-view :style="itemStyle"><slot name="swiperItem" :item="items[items.length - 1]"></slot></wbx-view>
        <wbx-view v-for="(item, index) in items" :key="index" :style="itemStyle"><slot name="swiperItem" :item="item"></slot></wbx-view>
        <wbx-view :style="itemStyle"><slot name="swiperItem" :item="items[0]"></slot></wbx-view>
      </wbx-view>
      <wbx-view v-if="indicatorDots" :style="{ width: containerWidth + 'px' }" style="position: absolute; bottom: 10px; display: flex; flex-direction: row; justify-content: center;">
        <wbx-view
          v-for="(item, index) in items"
          :key="index"
          :style="{ backgroundColor: index === realIndex ? indicatorActiveColor : indicatorColor }"
          style="width: 10px; height: 10px; margin: 0 5px; cursor: pointer; border-radius: 10px;"
          @click~stop="setCurrentIndex(index)"
        ></wbx-view>
      </wbx-view>
    </wbx-view>
  </template>
  
  <script>
  export default {
  /*
  items                 数据
  autoPlay              是否自动播放
  interval              自动播放间隔时间
  indicatorDots         是否显示指示点
  indicatorColor        指示点颜色
  indicatorActiveColor  当前选中的指示点颜色
  current               当前所在滑块的index
  vertical              滑动方向是否为纵向
  @change               轮播图改变时会触发 change 事件,返回当前索引值
  */
    props: {
      items: {
        type: Array,
        required: true
      },
      autoPlay: {
        type: Boolean,
        default: false
      },
      interval: {
        type: Number,
        default: 3000
      },
      indicatorDots: {
        type: Boolean,
        default: true
      },
      indicatorColor: {
        type: String,
        default: '#c0c0c0'
      },
      indicatorActiveColor: {
        type: String,
        default: '#fff'
      },
      current: {
        type: String,
        default: ''
      },
      vertical: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        currentIndex: 1,
        timer: null,
        startX: 0,
        startY: 0,
        offset: 0,
        isTransitioning: false,
        containerWidth: 0,
        containerHeight: 0
      };
    },
    watch: {
      current(newVal) {
        this.setCurrentIndex(newVal);
      }
    },
    computed: {
      wrapperStyle() {
        return {
          backgroundColor: "rebeccapurple",
          position: "relative",
          width: `${this.wrapperWidth}px`,
          height: `${this.wrapperHeight}px`,
        };
      },
      carouselStyle() {
        const baseTranslateValue = -this.currentIndex * (this.vertical ? this.containerHeight : this.containerWidth);
        const translateValue = baseTranslateValue + this.offset;
        console.log(this.offset,baseTranslateValue,translateValue,"999999")
        return {
          display: 'flex',
          flexDirection: this.vertical ? 'column' : 'row',
          transform: this.vertical ? `translateY(${translateValue}px)` : `translateX(${translateValue}px)`,
          transition: this.isTransitioning ? 'transform 0.3s ease-out' : 'none',
           width: !this.vertical ? `${this.wrapperWidth}px` : `${this.containerWidth}px`,
          height: this.vertical ? `${this.wrapperHeight}px` : `${this.containerWidth}px`
        };
      },
      wrapperWidth() {
        return this.containerWidth * (this.items.length + 2);
      },
      wrapperHeight() {
        return this.containerHeight * (this.items.length + 2);
      },
      itemStyle() {
        return {
          width: !this.vertical ? `${this.containerWidth}px` : `${this.containerWidth}px`,
          height: this.vertical ? `${this.containerHeight}px` : `${this.containerWidth}px`,
          flexShrink: 0
        };
      },
      realIndex() {
        return (this.currentIndex - 1 + this.items.length) % this.items.length;
      }
    },
    mounted() {
      this.updateDimensions();
      this.$nextTick(() => {
        if (this.autoPlay) {
          this.startAutoPlay();
        }
      });
    },
    beforeDestroy() {
      this.stopAutoPlay();
    },
    methods: {
      updateDimensions() {
        if (this.$refs.objStyle) {
          const objStyle =  this.$refs.objStyle.styleObject
          this.containerWidth = parseFloat(objStyle.width);
          this.containerHeight = parseFloat(objStyle.height);
        }
      },
      startAutoPlay() {
        this.timer = setInterval(() => {
          this.next();
        }, this.interval);
      },
      stopAutoPlay() {
        if (this.timer) {
          clearInterval(this.timer);
          this.timer = null;
        }
      },
      next() {
        this.offset = 0;
        this.isTransitioning = true;
        this.currentIndex += 1;
        this.$emit('change', { current: this.currentIndex });
      },
      prev() {
        this.offset = 0;
        this.isTransitioning = true;
        this.currentIndex -= 1;
        this.$emit('change', { current: this.currentIndex });
      },
      setCurrentIndex(index) {
        this.stopAutoPlay();
        this.isTransitioning = true;
        this.currentIndex = index + 1;
        if (this.autoPlay) {
          this.startAutoPlay();
        }
      },
      onTouchStart(e) {
        this.startX = e.touches[0].clientX;
        this.startY = e.touches[0].clientY;
        this.offset = 0;
        this.stopAutoPlay();
      },
      onTouchMove(e) {
        const moveX = e.touches[0].clientX;
        const moveY = e.touches[0].clientY;
        this.offset = this.vertical ? moveY - this.startY : moveX - this.startX;
      },
      onTouchEnd() {
        this.isTransitioning = true;
        if (Math.abs(this.offset) > (this.vertical ? this.containerHeight : this.containerWidth) /6) {
          if (this.offset > 0) {
            this.prev();
          } else {
            this.next();
          }
        } else {
          this.offset = 0;
        }
        if (this.autoPlay) {
          this.startAutoPlay();
        }
      },
      onTransitionEnd() {
        this.isTransitioning = false;
        this.offset = 0;
        if (this.currentIndex === this.items.length + 1) {
          this.currentIndex = 1;
        }
        if (this.currentIndex === 0) {
          this.currentIndex = this.items.length;
        }
      }
    }
  };
  </script>
  
  <style>
  </style>
相关推荐
miss6 分钟前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan1 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真1 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment1 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan1 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么1 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技2 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥2 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易2 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
恋猫de小郭3 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter