uniapp mixin 使用


創建 ListMoreDataMixin

// 由於沒有超類的限制這里要判斷下
function ____checkGetData(context) {
  if (!context.getData || typeof context.getData !== "function") {
    throw new Error("使用[ListMoreDataMixin]必須實現getData函數");
  }
}

export const ListMoreDataMixin = {
  data() {
    return {
      listData: [], // 數據列表
      page: 1, // 1
      limit: 10,
      isLoading: false, // 是否在加載數據
      isRefresh: false, // 下拉刷新

      autoInitListData: true,
    };
  },
  methods: {
    // 初始化數據
    async initData() {
      ____checkGetData(this);
      this.page = 1;
      this.isLoading = true;
      const data = await this.getData();
      this.listData = data;
      this.isLoading = false;
    },

    // 上拉加載更多
    async loadMore() {
      ____checkGetData(this);
      this.isLoading = true;
      this.page += 1;

      const data = await this.getData();

      // 沒有更多了
      if (!data || !data.length) {
        this.page--;
        if (this.notMoreData) {
          this.notMoreData?.();
        } else {
          uni.showToast({
            title: "到底了...",
            icon: "none",
          });
        }
      }

      this.listData = [...this.listData, ...data];
      this.isLoading = false;
    },

    // 下拉刷新
    async onRefresh(done) {
      ____checkGetData(this);
      this.isRefresh = true;
      await this.initData();
      this.isRefresh = false;
      if (done && typeof done === "function") done();
    },
  },
  mounted() {
    if (this.autoInitListData) this.initData();
  },
};

在組件中使用

<template>
    <scroll-view
      v-if="listData.length"
      :scroll-y="true"
      :scroll-with-animation="true"
      :refresher-enabled="true"
      :refresher-triggered="isRefresh"
      @refresherrefresh="onRefresh"
      @scrolltolower="loadMore"
    >
      <list-item v-for="item of listData" :key="item.id" :data="item" />
    </scroll-view>
</template>

<script>
import { ListMoreDataMixin } from 'list-more-data-mixin.js';

export default {
  mixins: [ListMoreDataMixin],
  methods: {
    // 必須實現
    async getData() {
      return this.api.get("/api/xxx", { page: this.page, limit: this.limit });
    },
  }
};
</script>

長列表

看這里

創建 LongListMoreDataMixin

// 由於沒有超類的限制這里要判斷下
function ____checkGetData(context) {
  if (!context.getData || typeof context.getData !== "function") {
    throw new Error("使用[LongListMoreDataMixin]必須實現getData函數");
  }
}

export const LongListMoreDataMixin = (manage) => {
  const PAGE = 1;
  const LIMIT = 20;
  return {
    data() {
      return {
        sections: [],
        page: PAGE,
        limit: LIMIT,
        isLoading: false, // 是否在加載數據
        isRefresh: false, // 下拉刷新

        autoInitListData: true,
      };
    },
    methods: {
      // 初始化數據
      async initData() {
        ____checkGetData(this);
        this.page = PAGE;
        this.isLoading = true;
        this._list = manage.clear();
        this.sections = [];
        const data = await this.getData();
        
        this._appendData(data);
        this.isLoading = false;
      },

      // 上拉加載更多
      async loadMore() {
        ____checkGetData(this);
        this.isLoading = true;
        this.page += 1;

        const data = await this.getData();

        // 沒有更多了
        if (!data || !data.length) {
          this.page--;
          if (this.notMoreData) {
            this.notMoreData?.();
          } else {
            uni.showToast({
              title: "到底了...",
              icon: "none",
            });
          }
        }

        this._appendData(data);
        this.isLoading = false;
      },

      // 下拉刷新
      async onRefresh(done) {
        ____checkGetData(this);
        this.isRefresh = true;
        await this.initData();
        this.isRefresh = false;
        if (done && typeof done === "function") done();
      },

      _addSection(data) {
        if (!data.length) return;
        this.sections.push({
          begin: this._list.length - data.length,
          end: this._list.length
        })
      },
      
      _appendData(data) {
        this._list.push(...data);
        this._addSection(data);
      }
    },
    mounted() {
      if (this.autoInitListData) this.initData();
    },
  };
}

組件中將你的列表分段

<template>
  <view>
    <my-section v-for="(item, index) in sections" :key="index" :section="item"></my-section>
  </view>
</template>

<script>
import manage from './list-manage';
import { LongListMoreDataMixin } from './LongListMoreDataMixin.js';

export default {
  mixins: [LongListMoreDataMixin(manage)],
  onPullDownRefresh() {
    this.onRefresh(() => {
      uni.stopPullDownRefresh();
    });
  },
  onReachBottom() {
    this.loadMore();
  },
  methods: {
    getData() {
      return new Promise(_res => {
        this.request({
          page: this.page,
          size: this.limit,
          success: res => {
            _res(res);
          }
        });
      });
    }
  }
};
</script>

my-section:

<template>
  <my-item v-for="(item, index) in list" :key="index" :data="item"></my-item>
</template>

<script>
import manage from './list-manage';

export default {
  props: ['section'],
  data() {
    return {
      list: []
    };
  },
  created() {
    this.list = manage.getSection(this.section);
  }
};
</script>

<style></style>

list-manage.js 中導出靜態列表,和一些管理函數

const manage = {
  list: [],
  clear() {
    return manage.list = []
  },
  getSection(section) {
    return manage.list.slice(section.begin, section.end);
  }
}

export default manage;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM