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

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

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>
相关推荐
2301_789169546 分钟前
react crash course 2024(9) proxying
前端·javascript·react.js
计算机学姐15 分钟前
基于nodejs+vue的超市管理系统
前端·javascript·vue.js·vscode·前端框架·node.js·ecmascript
Z_B_L17 分钟前
three.js----快速上手,如何用vue在web页面中导入 gltf/glb , fbx , obj 模型
开发语言·前端·javascript
谢尔登18 分钟前
webpack 和 vite 区别
前端·webpack·node.js
诗雅颂19 分钟前
【js逆向学习】qqmusic(qq音乐)webpack智能导出
javascript·学习·webpack
重生之我在20年代敲代码40 分钟前
HTML讲解(三)通用部分
前端·笔记·html
_.Switch1 小时前
Python Web 开发中的DevOps 实践与自动化运维
运维·开发语言·前端·python·架构·serverless·devops
计算机学姐1 小时前
基于nodejs+vue的宠物医院管理系统
前端·javascript·vue.js·mysql·npm·node.js·sass
余生H1 小时前
前端大模型入门:使用Transformers.js手搓纯网页版RAG(二)- qwen1.5-0.5B - 纯前端不调接口
前端·javascript·人工智能·大语言模型·rag·端侧大模型·webml
科研online2 小时前
ArcGIS Pro高级地图可视化—双变量符号地图
开发语言·javascript·arcgis