Drag and drop the page up and down on the mobile terminal to switch data display

When the user drags and drops the page, the data switching display of different modules of the current page is performed - based on this demo implemented by uniaap as an example:

parent component:

<template>
	<full-page :active-index.sync="activeIndex" :total-page="totalPage">
		<view class="section" v-for="(item, index) in totalPage" :key="index">
			<view :class="'page page-' + index">
				<view class="list">
					<view class="item red" v-if="index == 0">
					  第1页
					</view>
					<view class="item red" v-if="index == 1">
					  第2页
					</view>
					<view class="item red" v-if="index == 2">
					   第3页
					</view>
					<view class="item red" v-if="index == 3">
					   第4页
					</view>
				</view>
			</view>
		</view>
	</full-page>
</template>

<script>
	import FullPage from '@/components/search/FullPage/FullPage.vue';
	export default {
		components: {
			FullPage
		},
		data() {
			return {
				activeIndex:0,
				totalPage: 4
			}
		}
	}
</script>
<style lang="scss" scoped>
	page {
		height: 100%;
	}
	.section {
		height: 100%;
		width: 100%;
		position: relative;
	}
	.page {
		height: 100%;
		width: 100%;
		text-align: center;
		font-size: 50rpx;
		box-sizing: border-box;
		.item {
			height: 100%;
		}
	}
</style>

Subassembly:

<template>
  <view class="full-page-container">
    <view
      class="full-page-main"
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
      :style="style"
    >
      <slot />
    </view>
  </view>
</template>

<script>
  export default {
    name: 'FullPage',
    props: {
      // 触发翻页的临界值
      critical: {
        type: Number,
        default: 50,
      },
      // 总共页面数
      totalPage: {
        type: Number,
        required: true,
        default: 0,
      },
      // 当前页面的索引值
      activeIndex: {
        type: Number,
        required: true,
        default: 0,
      },
    },
    data() {
      return {
        pageIndex: 0, // 当前页面的索引值
        startPageY: 0, // 开始的位置
        endPageY: 0, // 结束的位置
        marginTop: 0, // 滑动下拉(上拉)距离
      }
    },
    mounted() {
      this.pageIndex = this.activeIndex
    },
    computed: {
      style() {
        return `transform:translateY(-${this.pageIndex * 100}%);margin-top:${
          this.marginTop
        }px`
      },
    },
    watch: {
      activeIndex(value) {
        this.pageIndex = value
      },
    },
    methods: {
      // 开始滑动
      handleTouchStart(e) {
        const { pageY } = e.touches[0]
        this.startPageY = pageY
      },
      // 滑动中
      handleTouchMove(e) {
        const { pageY } = e.touches[0]
        if (
          pageY - this.startPageY < this.critical &&
          pageY - this.startPageY > -this.critical
        ) {
          this.marginTop = pageY - this.startPageY
        }
        this.endPageY = pageY
      },
      // 滑动结束
      handleTouchEnd() {
        if (!this.endPageY) {
          return
        }
        if (
          this.endPageY - this.startPageY > this.critical &&
          this.pageIndex > 0
        ) {
          this.pageIndex -= 1
        } else if (
          this.endPageY - this.startPageY < -this.critical &&
          this.pageIndex < this.totalPage - 1
        ) {
          this.pageIndex += 1
        }
        this.$emit('update:activeIndex', this.pageIndex)
        this.startPageY = 0
        this.endPageY = 0
        this.marginTop = 0
      },
    },
  }
</script>

<style lang="scss" scoped>
  .full-page-container {
    height: 100vh;
    // height: 100%;
    overflow: hidden;
    .full-page-main {
      height: 100%;
      transition: all 0.3s;
    }
  }
</style>

Effect:

おすすめ

転載: blog.csdn.net/qq_63310300/article/details/131170946