实现效果
点击展开,每次累加五条数据进行展示
实现思路
- 起始本质上就是一个分页查询,只不过按新的形式展示,然后也不统计总数,每次只展示固定的5条数据
- 点击加载更多,就展示下一页,页的页数进行+1,请求后端接口获取下一页数据
- 获取到的新数据,通过与原数据集合找一个唯一维度比如ID,进行对比,不存在于原数据集中的,进行添加
- 还有一些小优化,比如数据为0时,以及最后一页时就不展示显示更多
具体代码
时间线自定义组件
<template>
<div style="display: flex; justify-content: center;">
<el-timeline style="max-width: 600px">
<el-timeline-item v-for="item in eventLogTableData" :timestamp="item.occurredAt" placement="top">
<el-card>
<h4>{{ item.channelName }}</h4>
<p>{{ item.actionDesc }}</p>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<div style="display: flex; justify-content: center;" v-if="eventLogTableData.length >0">
<el-button link type="primary" :icon="ArrowDownBold" @click="loadMore">加载更多</el-button>
</div>
<el-empty description="暂无数据" v-else/>
</template>
<script>
import {
h,
onUnmounted,
computed,
watch,
onMounted,
toRefs,
reactive,
ref,
} from "vue";
import {ArrowDownBold} from "@element-plus/icons-vue";
import {useStore} from "vuex";
export default {
components: {},
props: {
getDataSource: Function,
},
setup: function (props, context) {
const store = useStore();
const eventLogTableData = computed(() => store.state.member.eventLogTableData);
const eventLogPageSize = computed(() => store.state.member.eventLogPageSize);
const eventLogCurPage = computed(() => store.state.member.eventLogCurPage);
onUnmounted(() => {
store.commit("member/SET_EVENT_LOG_TABLE_PAGE_SIZE", 5, {root: true});
store.commit("member/SET_EVENT_LOG_TABLE_CUR_PAGE", 1, {root: true});
store.commit("member/SET_EVENT_LOG_TABLE_LIST", []);
});
const loadMore = () => {
store.commit("member/SET_EVENT_LOG_TABLE_CUR_PAGE", (eventLogCurPage.value + 1), {root: true});
// 调用父组件传来的加载数据函数
props.getDataSource();
};
return {
loadMore,
ArrowDownBold,
eventLogTableData,
eventLogPageSize,
eventLogCurPage
};
}
}
</script>
<style scoped lang="scss">
</style>
全局状态管理
import requestHttp from "@/server/request";
import {ElMessage} from "element-plus";
import util from "@/utils/utils";
import apiConstants from "@/api/apiConstants";
const state = {
eventLogTableData: [],
// 当前页
eventLogCurPage: 1,
// 页数量
eventLogPageSize: 5,
};
const mutations = {
SET_EVENT_LOG_TABLE_LIST: (state, payload) => {
state.eventLogTableData = payload || [];
},
SET_EVENT_LOG_TABLE_CUR_PAGE: (state, payload) => {
state.eventLogCurPage = payload;
},
SET_EVENT_LOG_TABLE_PAGE_SIZE: (state, payload) => {
state.eventLogPageSize = payload;
},
};
const actions = {
async pageQueryMemberEventLog({commit}, params) {
try {
const result = await requestHttp({
// 这里按情况写自己的
url: apiConstants.HOST_HOME_GET_MEMBER_EVENT_LOG_INFO,
method: "POST",
data: params,
});
if (result.data && result.data.code == 200) {
let data = result.data?.data.list;
let copiedArray = state.eventLogTableData.slice();
let ids = copiedArray.map(item => item.id);
// 这里将不存在于原数据的返回结果写入
let canUseData = data.filter(item => !ids.includes(item.id));
copiedArray.push(...canUseData);
commit("SET_EVENT_LOG_TABLE_LIST", copiedArray);
} else {
ElMessage.warning(result.data.message);
}
} catch (e) {
console.log(e);
}
},
};
export default {
namespaced: true,
state,
mutations,
actions,
};
父组件
<template>
<MemberEventLogTimeLine :getDataSource="getMemberEventLogDataSource"></MemberEventLogTimeLine>
</template>
<script>
import MemberEventLogTimeLine from "views/member/MemberEventLogTimeLine.vue";
import {useStore} from "vuex";
// 分页查询事件
export default {
components: {MemberEventLogTimeLine},
props: {},
setup: function (props, context) {
const store = useStore();
const memberId = computed(() => store.state.member.currentMemberId);
const eventLogCurPage = computed(() => store.state.member.eventLogCurPage);
const eventLogPageSize = computed(() => store.state.member.eventLogPageSize);
const getMemberEventLogDataSource = () => {
const params = {
pageNum: eventLogCurPage?.value,
pageSize: eventLogPageSize?.value,
param: {memberId: memberId?.value}
};
store.dispatch("member/pageQueryMemberEventLog", params);
}
}
}
</script>