const tabchange=e=>{
data.activity = e
vedioLoad(data.activity)//加载数据 加载的时候传值过去
}
解决方法:
使用标识符来进行辨认 有两个tab页 搞个动态加载 在开头的vedioload还没开始加载的时候判断是否加载过 入股已经加载过 则返回 不要重新加载
loadvideos会根据loadedTabs的状态决定是否需要加载数据
改动
videos.value = filterSelectData 改为
videos.value[videoTypeFilter] = filterSelectData;
由标签页的离线和在线数据 都分开管理 使用两个列表:即一个数组两个对象进行存储 数组的下标有tab0 tab1 动态决定 代替原来的直接覆盖数据
const loadVideos = (videoTypeFilter) => {
if (loadedTabs.value[videoTypeFilter]) {
// 如果数据已经加载过了,直接返回
data.loading = false;
return;
}
// 数据尚未加载,执行加载逻辑
// ...加载数据的代码...
loadedTabs.value[videoTypeFilter] = true; // 数据加载完成后,设置为true
}
const tabsChange = e => {
data.activeKey = e;
loadVideos(data.activeKey); // 调用loadVideos来加载数据
};
单页全部代码
<!-- 宣传教育 -->
<template>
<div class="video-section">
<div class="box-header block-interval">
<div class="title">
<a-tabs v-model:activeKey="activeKey" @change="tabsChange">
<a-tab-pane key=1 tab="在线" />
<a-tab-pane key=0 tab="离线" />
</a-tabs>
</div>
</div>
<div class="backcolor">
<div class="search-bar">
<!-- 搜索 -->
<a-form-item label="视频课程:">
<a-input v-model:value="where.videoTitle" placeholder="请搜索视频课程" allow-clear />
</a-form-item>
<a-button type="primary" @click="reload" class="searchBtn">
<img src="@/assets/icon/archives/select.png" alt="" class="searchIcon" />
查询
</a-button>
</div>
<a-spin :spinning="loading">
<div class="video-gallery">
<div v-for="video in videosForCurrentTab" :key="video.id">
<div class="video-container">
<video :id="`video-${video.id}`" controls muted class="video-player">
<source :src="video.fileUrl" type="video/mp4" />
</video>
</div>
<div class="video-item-wrapper">
<div class="video-title">{{ video.videoTitle }}</div>
</div>
</div>
</div>
</a-spin>
<div class="pagination-style">
<a-pagination :current="currentPage" :pageSize="pageSize" :total="total" @change="handlePageChange"
@showSizeChange="handlePageSizeChange" />
</div>
</div>
</div>
</template>
<script >
import { sysFileUploadUrl, previewFile } from '@/api/file/FileApi';
import { defineComponent, reactive, toRefs, onMounted, h, getCurrentInstance } from 'vue';
import { ref, computed } from 'vue';
import router from '@/router';
import { Modal, message } from 'ant-design-vue';
import { EducationApi } from '@/api/education/educationApi';
export default defineComponent({
setup() {
const videos = ref([]);
const loadedTabs = ref({});
//加载
const loadVideos = (videoTypeFilter) => {
data.loading =true;
// 检查是否已加载该标签页的数据
if (loadedTabs.value[videoTypeFilter]) {
data.loading =false;
return; // 如果已加载,直接返回
}
let result = EducationApi.getEducationListPage({
videoType: videoTypeFilter,
pageNo: data.currentPage,
pageSize: data.pageSize,
});
result.then(result => {
data.total = result.data.totalRows
let filterSelectData = result.data.rows.map(video => ({ ...video, selected: false }));
if (videoTypeFilter == 0) {
//调用处理路径的方法
filterSelectData = filterSelectData.map(video => {
if (video.fileId && video.fileId.trim() !== '') {
video.fileUrl = `http://172.24.8.11:9062/upms/sysFileInfo/publicDownload?fileId=${video.fileId}`;
}
return video
})
}
// videos.value = filterSelectData;
videos.value[videoTypeFilter] = filterSelectData;
loadedTabs.value[videoTypeFilter] = true;
debugger
data.loading =false;
})
}
const data = reactive({
where: {},
selection: [],
activeKey: "1",
id: 0,
currentPage: 1,
pageSize: 8, // 每页显示的条数
total: 20, // 总数据量,需要从后端获取
loading:false,
})
const tabsChange = e => {
data.activeKey = e;
loadVideos(data.activeKey)
};
onMounted(() => {
//在线视频
loadVideos(1)
});
const reload = () => {
let result = EducationApi.getEducationList({ videoTitle: data.where.videoTitle, videoType: data.activeKey });
result.then(res => {
videos.value = res.data;
})
}
//分页加载数据
const handlePageChange = newPage => {
data.currentPage = newPage;
loadVideos(data.activeKey); // 重新加载数据
};
//更改每页显示的数据量
const handlePageSizeChange = (current, size) => {
data.pageSize = size;
loadVideos(data.activeKey); // 重新加载数据
};
// 添加
const add = () => {
router.push('/edu/eduAdd');
};
const gotoDetail = (id) => {
router.push(`/edu/eduAdd?id=${id}`);
};
//删除id
const getSelectedVideoIds = () => {
console.log("getSelectedVideoIds" + JSON.stringify(videos.value));
return videos.value.filter(video => video.selected).map(video => video.id);
};
//删除
const del = item => {
let messages = null;
let params = { ids: [] };
const selectedVideoIds = getSelectedVideoIds();
if (selectedVideoIds.length === 0) {
return message.warning('请选择删除项');
}
messages = `是否要删除选中的【${selectedVideoIds.length}条】的视频?`
Modal.confirm({
title: h('div', {}, messages),
okText: '确定',
cancelText: '取消',
closable: true,
onOk: () => {
data.loading =true;
EducationApi.delEducation(selectedVideoIds).then(res => {
message.success('删除成功');
loadVideos(data.activeKey)
});
}
});
};
return {
...toRefs(data),
videos,
add,
del,
gotoDetail,
reload,
tabsChange,
previewFile,
handlePageChange,
handlePageSizeChange,
videosForCurrentTab: computed(() => videos.value[data.activeKey] || []),
// ...其他返回的属性或方法
};
}
})
</script>
<style lang="scss" scoped>
/* 样式保持不变 */
.ant-tabs {
width: 100%;
margin-top: -20px;
}
.backcolor {
background: #fff;
height: 100%;
}
.video-section {
background-color: #e7f1fb !important;
}
.box-header {
background: #fff;
height: 60px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
.title {
color: #333333;
padding: 20px 20px;
border-left: 4px solid #007cf0;
height: 5px;
}
.title-right {
display: flex;
width: 200px;
justify-content: space-between;
}
}
.search-bar {
display: flex;
gap: 10px;
justify-content: flex-end;
padding: 20px 20px;
}
.video-gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
/* 使每个视频元素至少300px宽,同时填满可用空间 */
gap: 1rem;
padding: 1rem;
flex-grow: 1;
}
.video-container {
background-color: black;
position: relative;
padding-top: 56.25%;
/* 16:9宽高比 */
}
.video-player {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.video-item-wrapper {
display: flex;
align-items: center;
justify-content: center;
.video-checkbox {
margin-right: 10px;
}
.video-title {
text-align: center;
margin-top: 0.5rem;
cursor: pointer;
}
}
.pagination-style {
display: flex;
justify-content: center;
margin-top: 20px;
}
/* 媒体查询,针对较小屏幕调整布局 */
@media (max-width: 800px) {
.video-gallery {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
/* 在较小屏幕上,减小视频元素的最小宽度 */
}
}
</style>