| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <template>
- <view>
- <!-- @scrolltolower="scrolltolower" -->
- <up-list style="height: auto" id="item_height" class="wrap_list">
- <up-list-item v-for="(item, index) in lists" :key="index">
- <slot name="item" :item="item" :index="index"></slot>
- </up-list-item>
- </up-list>
- <view class="null_warp" v-if="isLoaded && !lists.length && !isLoading">
- <slot name="null">
- <view class="null_text">{{ t(nullText || "无数据") }}</view>
- </slot>
- </view>
- <template v-if="(!!status && lists.length) || isLoading">
- <view class="load_more">
- <u-loadmore
- :status="status"
- :loading-text="t(loadingText)"
- :loadmore-text="t(loadmoreText)"
- :nomore-text="t(nomoreText)"
- />
- </view>
- </template>
- </view>
- </template>
- <script setup>
- import { query, $post, systemInfo } from "@/utils";
- import { ref, nextTick, computed } from "vue";
- import { t } from "@/locale";
- import { useCacheStore } from "@/store";
- const useCache = useCacheStore();
- const props = defineProps({
- topHeight: {
- type: Number,
- default: 0,
- },
- url: {
- type: String,
- default: "",
- },
- pageSize: {
- type: Number,
- default: 10,
- },
- defaultParams: {
- type: Object,
- default: () => {},
- },
- nullText: String,
- loadingText: {
- type: String,
- default: "正在加载中",
- },
- loadmoreText: {
- type: String,
- default: "加载更多",
- },
- nomoreText: {
- type: String,
- default: "没有更多了",
- },
- getIndex: {
- type: Number,
- default: 0,
- },
- activeIndex: {
- type: Number,
- default: 0,
- },
- isCache: Boolean,
- isLoading: Boolean,
- });
- const emit = defineEmits(["datas"]);
- const lists = ref([]);
- const page = ref(1);
- const totals = ref(0);
- const status = ref("nomore");
- const noData = ref(false);
- const height = ref(0);
- const isLoaded = ref(false);
- const scrolltolower = () => {
- if (!noData.value) {
- let num = page.value;
- num += 1;
- page.value = num;
- nextTick(() => {
- getData(true);
- });
- }
- };
- const deleteSpace = (str) => {
- return str.replace(/\s+/g, "");
- };
- const getData = async (flag = false) => {
- let newFlag = flag;
- const _list = useCache.getShopList(
- props.defaultParams?.channel,
- props.defaultParams?.keyWord
- );
- if (_list && props.isCache && !flag) {
- let search_text =
- props.defaultParams.keyWord && deleteSpace(props.defaultParams.keyWord);
- const searchKey = `search_${search_text}`;
- const { page: pageNum, children } = _list;
- page.value = pageNum;
- if (children[searchKey]) {
- lists.value = children[searchKey];
- emit("datas", children[searchKey]);
- nextTick(() => {
- getHeight();
- });
- } else {
- newFlag = true;
- }
- isLoaded.value = true;
- if (newFlag) {
- } else {
- return;
- }
- }
- try {
- status.value = "loading";
- const {
- data: {
- data: { item: data, total_results: count },
- },
- } = await $post(
- props.url,
- {
- pageSize: props.pageSize,
- page: page.value,
- ...props.defaultParams,
- },
- { isLoading: props.isLoading }
- );
- status.value = "nomore";
- if (data.length >= count) {
- noData.value = true;
- } else {
- noData.value = false;
- }
- totals.value = count - 0;
- if (page.value > 1) {
- const arrList = lists.value;
- lists.value = [...arrList, ...data];
- !props.defaultParams.img &&
- useCache.setShopList(
- props.defaultParams.channel,
- page.value,
- data,
- props.defaultParams.keyWord
- );
- emit("datas", lists.value);
- nextTick(() => {
- getHeight();
- });
- return;
- }
- lists.value = data;
- isLoaded.value = true;
- !props.defaultParams.img &&
- useCache.setShopList(
- props.defaultParams.channel,
- page.value,
- data,
- props.defaultParams.keyWord
- );
- emit("datas", lists.value);
- nextTick(() => {
- getHeight();
- });
- } catch (error) {
- console.error(error, "getData");
- isLoaded.value = true;
- }
- };
- const getHeight = async (name = "#item_height") => {
- const { height: heights } = await query(name, this);
- nextTick(() => {
- height.value = heights || 0;
- const { windowHeight, statusBarHeight } = systemInfo();
- let contHeight = windowHeight - 44 - props.topHeight;
- if (height < contHeight) {
- scrolltolower();
- }
- });
- return height;
- };
- const handleRefresh = (flag = false) => {
- page.value = 1;
- status.value = "nomore";
- noData.value = false;
- isLoaded.value = false;
- if (!flag) {
- lists.value = [];
- }
- nextTick(() => {
- getData(flag);
- });
- };
- const setList = (_list) => {
- nextTick(() => {
- lists.value = _list;
- emit("datas", lists.value);
- nextTick(() => {
- getHeight();
- });
- });
- };
- defineExpose({
- handleRefresh,
- setList,
- getData,
- scrolltolower,
- });
- </script>
- <style lang="less" scoped>
- @import url("@/style.less");
- :deep(.u-list) {
- height: 100% !important;
- }
- /deep/ .uni-scroll-view {
- overflow: unset !important;
- }
- .null_warp {
- .null_text {
- min-height: 100rpx;
- .flex_center();
- font-size: 28rpx;
- color: #333;
- }
- }
- .load_more {
- padding: 16rpx 0;
- }
- </style>
|