vue项目之移动端better-scroll的使用

vue项目之移动端better-scroll的使用

vue项目之移动端better-scroll的使用

封装better-scroll

<template>
  <div class="wrapper" ref="wrapper">
    <div>
      <slot></slot>
    </div>
  </div>
</template>

<script>
import BScroll from "better-scroll";

export default {
  name: "Scroll",
  props: {
    probeType: {
      type: Number,
      default: 1,
    },
    data: {
      type: Array,
      default: () => {
        return [];
      },
    },
    pullUpLoad: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      scroll: {},
    };
  },
  mounted() {
    setTimeout(this.__initScroll, 20);
  },
  methods: {
    __initScroll() {
      // 1.初始化BScroll对象
      if (!this.$refs.wrapper) return;
      this.scroll = new BScroll(this.$refs.wrapper, {
        probeType: this.probeType,
        click: true, // 鼠标点击滚动
        // tap: true,
        // mouseWheel: true, //鼠标滚轮滚动
        pullUpLoad: this.pullUpLoad,
      });

      // 2.将监听事件回调
      this.scroll.on("scroll", (pos) => {
        this.$emit("scroll", pos);
      });

      // 3.监听上拉到底部
      this.scroll.on("pullingUp", () => {
        console.log("上拉加载");
        this.$emit("pullingUp");
      });
    },
    refresh() {
      this.scroll && this.scroll.refresh && this.scroll.refresh();
    },
    finishPullUp() {
      this.scroll && this.scroll.finishPullUp && this.scroll.finishPullUp();
    },
    scrollTo(x, y, time = 500) {
      this.scroll && this.scroll.scrollTo && this.scroll.scrollTo(x, y, time);
    },
  },
  watch: {
    data() {
      setTimeout(this.refresh, 20);
    },
  },
};
</script>

<style scoped>

</style>

组件使用

<template>
  <div class="home">
    <baseTitleBar
      backgroundColor="#FFF"
      :leftEle="leftEle"
      :title="title"
      titleColor="#000"
    ></baseTitleBar>
    
    <scroll
      class="content"
      ref="scroll"
      @pullingUp="loadMore"
      @scroll="contentScroll"
      :data="data"
      :pull-up-load="enableLoadMore"
      :probe-type="3"
    >
      <!-- 轮播图 -->
      <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
        <van-swipe-item v-for="(item, idx) in swipeList" :key="idx">
          <img :src="item.target" alt="" class="swiper-img" />
        </van-swipe-item>
      </van-swipe>
      
      <!-- 列表 -->
      <div
        class="advert-item click w702 bg-fff"
        v-for="(item, idx) in data"
        :key="idx"
        @click="gotoAdvDetail(item.resource_id)"
      >
        <div class="adv-left">
          <div class="fs-30 color-000 flex-center">
            <span
              class="label fs-24"
              :class="{
                label: item.rank == '一级屏',
                label2: item.rank == '二级屏',
                label3: item.rank == '三级屏',
                label4: item.rank == '四级屏',
              }"
            >
              {{ item.atlas.category }}
            </span>
            <span class="adv-title font-bold text-el">
              {{ item.resource_info }}
            </span>
          </div>
          <div class="flex-center mt-15">
            <div class="tag fs-24 text-el">{{ item.resource_info }}</div>
            <div class="line"></div>
          </div>
          <div class="fs-24 color-333 mt-10 text-el" style="width: 4.9rem">
            {{ item.atlas.desc }}
          </div>
          <div class="mt-24">
            <span class="coin fs-28">收藏量{{ item.atlas.like_count }}</span>
            <span class="qty fs-20 ml-24">
              曝光量{{ item.atlas.favorite_count }}
            </span>
          </div>
        </div>
        <div class="adv-right">
          <div class="adv-img">
            <img :src="item.target" alt="" @load="imageLoad" />
          </div>
          <div class="dist fs-20" v-if="item.distance">
            {{ item.atlas.sender.username }}
          </div>
        </div>
      </div>
    </scroll>
    <BackTop @click.native="gobackTop" v-show="showBackTop"></BackTop>
  </div>
</template>

<script>
import baseTitleBar from "@/components/titleBar/baseTitleBar";
import scroll from "../components/scroll";
import BackTop from "../components/backTop.vue";
import { homeSwipeList, homeGoodsList } from "@/api/home";

export default {
  name: "home",
  components: { scroll, baseTitleBar, BackTop },
  data() {
    return {
      page: 1,
      limit: 10,
      data: [],
      swipeList: [],
      leftEle: {
        iconName: "iconback",
        color: "#000",
        fontSize: ".36rem",
        method: this.back,
      },
      title: "首页",
      showBackTop: false,
      backTopDistance: 800,
      enableLoadMore: true
    };
  },
  methods: {
    // 请求轮播数据
    async gethomeSwipeList() {
      let res = await homeSwipeList();
      this.swipeList = res.item;
    },
    // 请求列表数据
    getListData() {
      let params = {
        // 页数
        page: this.page,
        limit: this.limit,
      };
      homeGoodsList(params).then((res) => {
        if (res.code == 200) {
          if (this.data.length >= res.item.total) {
            this.enableLoadMore = false;
            return;
          }
          // this.data = this.data.concat(res.item.resultList);
          const homeGoodsList = res.item.resultList;
          this.data.push(...homeGoodsList);
          this.page += 1;
          this.$refs.scroll.finishPullUp();
        } else {
          console.log("接口出错");
        }
      });
    },
    // 加载更多
    loadMore() {
      this.getListData();
      // 用于图片异步加载高度问题刷新
      this.$refs.scroll.refresh();
    },
    // 监听回顶的显示
    contentScroll(position) {
      // 1.决定tabFixed是否显示
      // this.isTabFixed = position.y < -this.tabOffsetTop;
      // 2.决定backTop是否显示
      this.showBackTop = -position.y > this.backTopDistance;
    },
    // 回到顶部
    backTop() {
      this.$refs.scroll.scrollTo(0, 0, 300);
    },
    // 跳转详情
    gotoAdvDetail(id) {
      console.log(id);
      this.$router.push({ path: "/detail", query: { id: id } });
    },
    // 回到顶部
    gobackTop() {
      // console.log("回到顶部", this.$refs.scroll);
      // 第一种写法 this.$refs.scroll 拿到scroll组件里面的scroll , 然后调用里面的方法 , 第一二参数为距离, 第三个参数为时间500ms
      // this.$refs.scroll.scroll.scrollTo(0, 0, 500);
      // 第二种写法
      this.$refs.scroll.scrollTo(0, 0, 500);
    },
    imageLoad(){
      console.log('图片加载完触发事件');
      // this.$bus.$emit('itemImageLoad')
    },
  },
  created() {
    this.gethomeSwipeList();
    this.getListData();
    // 监听item中图片加载完
    // this.$bus.$on('itemImageLoad', () => {
    //   console.log(111);
    // })
  },
};
</script>

<style scoped lang="scss">
.home {
  height: 100vh;
  position: relative;
}
.content {
  position: absolute;
  top: 0.9rem;
  bottom: 1.08rem;
  left: 0;
  right: 0;
  overflow: hidden;
}
// 轮播图
.my-swipe {
  width: 100%;
  height: 4.5rem;
}
.swiper-img {
  width: 100%;
  height: 4.5rem;
}
// 这部分是列表
.advert-item {
  margin-left: 0.24rem;
  height: 2.43rem;
  padding: 0.26rem 0.24rem 0;
  display: flex;
  justify-content: space-between;
  border-radius: 0.18rem;
  margin-bottom: 0.18rem;
  .label {
    width: 1.2rem;
    height: 0.34rem;
    line-height: 0.34rem;
    text-align: center;
    display: inline-block;
    background: linear-gradient(90deg, #fecb00 0%, #feba00 100%);
    border-radius: 0.08rem;
    font-size: 0.2rem;
    color: #fff;
  }
  .label2 {
    background: #c3d8e6;
    color: #fff;
  }
  .label3 {
    background: #e0c19d;
    color: #fff;
  }
  .label4 {
    background: #f5f5f5;
    color: #333333;
  }
  .adv-title {
    margin-left: 0.18rem;
    width: 3.5rem;
    display: inline-block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tag {
    color: #8c8c8c;
    max-width: 1.2rem;
  }
  .line {
    height: 0.19rem;
    background: #8c8c8c;
    margin: 0 0.23rem;
    position: relative;
    &::after {
      content: "";
      display: block;
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      -webkit-transform: scale(0.5, 1);
      transform: scale(0.5, 1);
      border-right: 1px solid #8c8c8c;
    }
    &:last-child::after {
      border: 0;
    }
  }
  .line-right {
    height: 0.19rem;
    background: #8c8c8c;
    margin: 0 0.23rem;
    position: relative;
    &::after {
      content: "";
      display: inline-block;
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      -webkit-transform: scale(0.5, 1);
      transform: scale(0.5, 1);
      border-right: 1px solid #8c8c8c;
    }
  }
  .border-none {
    &:last-child .line-right {
      &::after {
        border: 0;
      }
    }
  }
  .coin {
    color: #ccc;
  }
  .adv-img {
    width: 1.6rem;
    height: 1.6rem;
    border-radius: 0.18rem;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .dist {
    color: #8c8c8c;
    margin-top: 0.03rem;
    text-align: right;
  }
}
</style>

在这里插入图片描述

回顶封装

<template>
  <div class="back-top">
    <div class="up">顶部</div>
  </div>
</template>
<script>
export default {
  name: "backTop",
  data() {
    return {};
  },
  created() {},
  computed: {},
  methods: {},
};
</script>
<style lang="scss" scoped>
.back-top {
  width: 0.8rem;
  height: 0.8rem;
  border-radius: 50%;
  color: #fff;
  background: rgba(226, 34, 34, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  position: fixed;
  right: 0.2rem;
  bottom: 1.6rem;
  z-index: 999;
}
</style>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值