列表页面BackTop功能提供

80 阅读1分钟

列表页面与BackTop平滑滚动

前面所有的功能都是以Mixin的形式提供的,可以根据具体情况灵活组合。

当然也可以封装为组件。mixin的形式只作为一个参考。

现在继续以mixin的形式提供BackTop功能。

BackTopMixin

const BackTopMixin = {
  props: {
    // 是否需要使用BackTop
    showBackTop: {
      type: Boolean,
      default: true
    },
    backTopPosition: {
      type: Object,
      default() {
        return {
          bottom: 40,
          right: 40
        };
      }
    }
  },
  data() {
    return {
      // 只有达到一定的滚动高度才展示BackTop
      backTopVisible: false
    };
  },
  methods: {
    buildBackTop() {
      return this.showBackTop && (
        <BackTop
          visible={this.backTopVisible}
          position={this.backTopPosition}
          onClick={this.backTopSmoothly}
        />
      );
    },
    backTopSmoothly() {
      scrollTopSmoothly(this.getScroller());
    }
  }
};

结合ListWithScrollView

const ListByScrollView = {
  mixins: [BackTopMixin],
  props: {
    // 数据
    list: {
      type: Array,
      default() {
        return [];
      }
    },
  },
  watch: {
    async pageStatus() {
      await this.$nextTick();
      // 判断是否展示了List
      const scroller = this.getScroller();
      // 在dom上绑定bind-scroll属性标志已添加scroll事件
      if (!scroller && scroller.getAttribute('bind-scroll') !== null) return;
      scroller.addEventListener('scroll', this.handleScroll);
      scroller.setAttribute('bind-scroll', '');
      // 组件销毁前,一定要解绑事件
      this.$refs.component.$once('hook:beforeDestroy', () => {
        srcoller.removeEventListener('scroll', this.handleScroll);
      });
    }
  },
  methods: {
    renderList() {
      return (
        <ScrollView ref="component" onLoad={}>
          {this.list.map(item => <Item item={item} />)}
        </ScrollView>
      );
    },
    getScroller() {
      return this.$refs.component?.$el;
    },
    // 在这里控制BackTop的展示
    handleScroll(e) {
      if (this.showBackTop) {
        // 容器的高度与滚动高度
        const { clientHeight, scrollTop } = this.getScroller();
        this.backTopVisible = clientHeight < scrollTop;
      }
    }
  }
};