实现效果
点击展开,每次累加五条数据进行展示
实现思路
- 起始本质上就是一个分页查询,只不过按新的形式展示,然后也不统计总数,每次只展示固定的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>