当前位置: 首页 > 编程日记 > 正文

vue3解决切换tab页每次切换加载数据导致数据缓慢问题

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>

相关文章:

使用JavaScript实现复杂功能:一个完整的电商网站搜索功能

随着互联网的发展,电子商务网站已经成为人们购物的重要平台。而在这些网站中,搜索功能无疑是核心功能之一。用户可以通过搜索快速找到他们需要的商品,从而提高购物体验。本文将详细介绍如何使用JavaScript实现一个完整的电商网站搜索功能。

抖音直播原理解析-如何在 Web 中播放 FLV 直播流

Media Source Extensions API(MSE)媒体源扩展 API 提供了实现无插件且基于 Web 的流媒体的功能,不同于简单的使用video元素,video元素对于开发者来说完全是一个黑盒,浏览器自己去加载数据,加载完了自己解析,解码再播放,这个过程中开发者无法进行任何操作。利用 MSE API 开发者可以自定义获取流媒体数据并且还可以对数据做一些操作。MSE 的兼容性如下图所示。可以发现 MSE 的兼容性还算可以,IE 11 都支持。

JavaScript DOM之Cookie详解

随着互联网的不断发展各种基于互联网的服务系统逐渐多了起来,我们常常需要记录访问者的一些信息,比如用户的账号,购物车存储的商品等,就需要用到cookie技术。cookie最早是网景公司发明的,是一种跟踪用户会话的技术。可以理解为本地缓存,它由服务器生成,保存在用户本地浏览器上的小文本文件,它可以包含与用户相关的信息。

说说你对 TypeScript 的理解?与 JavaScript 的区别?

超集,不得不说另外一个概念,子集,怎么理解这两个呢,举个例子,如果一个集合 A 里面的的所有元素集合 B 里面都存在,那么我们可以理解集合 B 是集合 A 的超集,集合 A 为集合 B 的子集。其是一种静态类型检查的语言,提供了类型注解,在代码编译阶段就可以检查出数据类型的错误。通过类型批注提供在编译时启动类型检查的静态类型,这是可选的,而且可以忽略而使用。如果缺乏声明而不能推断出类型,那么它的类型被视作默认的动态。等数据格式,对象的类型就是用接口来描述的。的语法,所以任何现有的。对于基本类型的批注是。

elementPlust 的el-select在提示框关闭时自动弹出

主要问题就是因为filterable属性,根本解决方案是选中的时候让他失去焦点 el-select有一个visible-change事件,下拉框出现/隐藏时触发。当el-select添加filterable属性时,弹提示窗时,点击确定后,下拉框会自动弹出。console.log('弹窗出select', item)增加了visible-change事件。el-select事件最后增加焦点取消。

在 Spring MVC 中,用于接收前端传递的参数的注解常用的有以下几种

form-data参数使用multipart/form-data作为Content-Type,前端使用params格式传参,后端使用@RequestParam注解接收参数。- json请求体参数使用application/json作为Content-Type,前端使用data格式传参,后端使用@RequestBody注解接收参数。- 路径传参不需要设置Content-Type,前端将参数通过URL传递,后端使用@PathVariable注解接收参数。

在react中说说对受控组件和非受控组件的理解?以及应用场景

这时候当我们在输入框输入内容时,会发现输入的内容无法显示出来,此时input标签是一个可读的状态,因为value被this.state.username所控制,当用户输入时,this.state.username不会自动更新,这样的话input的内容就不会发生变化了,想要解除被控制,可以为input标签设置onChange事件,触发的时候更新state,从而导致input框内容更新。简单来讲,就是受我们控制的组件,组件的状态全程响应外部数据。

Python中如何简化if...else...语句

我们通常在Python中采用if...else..语句对结果进行判断,根据条件来返回不同的结果,如下面的例子。这段代码是一个简单的Python代码片段,让用户输入姓名并将其赋值给变量user_input。我们能不能把这几行代码进行简化,优化代码的执行效率呢?以下是对各行代码的解读。这里使用了or这个逻辑运算符,当user_input不为空时,user_input为真,name就被赋于user_input的值。采用这种方法可以轻松实现if...else语句的简化。我们可以使用一行简短的代码来实现上面的任务。

vue3 项目中 arguments 对象获取失败问题

在 vue3 项目中获取到的 arguments 对象与传入实参不符,打印出函数中的 arguments 对象如下...

前端JS代码中Object类型数据的相关知识

遍历JavaScript中的对象有几种方法,包括使用for…in循环、Object.keys()方法、Object.values()方法和Object.entries()方法。因此前端传入了日期类型数据之后,如果和后台数据库中的数据类型不一致,比如数据库中的日期数据类型格式是。前端传入的Object对象中其中某个字段值是日期类型的数据,则在前端的类型就是一个。,则数据传往后端之前需要做格式类型转换。,它的值是一个中国标准时间,比如。

深入解析JavaScript的原生原型

在JavaScript中,除了自定义对象,还存在很多由JavaScript语言本身提供的原生对象。这些原生对象同样基于原型继承机制,拥有自己的原型。理解原生对象的原型非常重要,可以让我们正确使用这些内置对象,也有助于进一步理解JavaScript的原型继承系统。本文将详细解析原生对象的原型结构,揭开一些常见原生对象原型的神秘面纱。​学习原生对象的原型关系,有助于我们在日常开发中正确理解和使用这些JavaScript内置对象,避免一些常见陷阱。

深入三目运算符:JavaScript、C++ 和 Python 比较

三目运算符是编程中常用的条件表达式,它允许我们根据条件选择不同的值。我们将通过具体的例子分别介绍 JavaScript、C++ 和 Python 中的三目运算符,以便更好地理解它们的用法和特性。JavaScript 示例// 例子: 根据条件选择不同的值var x = 10;var y = 20;"x 大于 y" : "x 不大于 y";在这个例子中,如果x大于y,则result的值为 “x 大于 y”,否则为 “x 不大于 y”。C++ 示例// 例子: 根据条件选择不同的值。

深入解析JavaScript中new Function语法

Function是JavaScript中非常重要的内置构造函数,可以用来动态创建函数。new Function语法就是其中一种函数创建方式。但是new Function也有一定的缺点需要注意。本文将带您深入解析new Function语法,了解其应用场景以及需要注意的问题。​new Function是动态创建函数的一种方式,但也有缺点。为了更好的代码质量和性能,应该慎用或避免使用。对JavaScript函数和作用域有深入理解,可以编写出更简洁、高效、稳定的代码。​。

javascript的变量存储机制和原理

js的变量存储机制

uniap vue3 组件使用uni.createSelectorQuery() 获取dom报错

批量查询时,结果是按照查询的顺序返回的。由于vue3中没有this,所以使用。

将 RGB 转换为十六进制、生成随机十六进制

RGB是一种加法混色模式,它通过调节红、绿、蓝三个颜色通道的亮度来混合出各种颜色。对于每个颜色通道,取值范围是0到255,0表示该通道对应的颜色分量没有亮度,255表示达到最大亮度。

nodemon(自动重启 node 应用程序)的安装与使用

(2).键入命令 set-ExecutionPolicy remoteSigned。windows 默认不允许 npm 全局命令执行脚本文件,所以需要修改执行策略。全局安装完成之后就可以在命令行的任何位置运行 nodemon 命令。(4)、再运行 nodemon app.js ok。我们可以执行安装选项 -g 进行全局安装。1、安装,在随意一个命令窗口都可以。自动重启 node 应用程序。(3)、输入Y 或者 A。

如何优化Uniapp应用程序的性能?

避免频繁的重绘和重排:频繁的DOM操作会导致浏览器频繁的重绘和重排,影响性能。使用v-for中的key属性:在使用v-for渲染列表时,为每个列表项添加唯一的key属性,这样可以减少渲染的次数,提高渲染的效率。减少页面加载时间:避免页面过多和过大的组件,减少不必要的资源加载。使用图片懒加载:对于图片较多的场景,可以使用图片懒加载的方式,当图片进入用户可视范围时再进行加载,减少初始页面加载的时间。节流和防抖:对于频繁触发事件的场景,可以使用节流和防抖的方法来减少事件处理的频率,从而提高性能。

鸿蒙开发-ArkTS基础,它与TS区别在那?

ArkTS是HarmonyOS优选的主力应用开发语言。ArkTS围绕应用开发在TypeScript(简称TS)生态基础上做了进一步扩展,继承了TS的所有特性,是TS的超集。说明: 也就是前端开发过程中所有的js/ts语法大部分支持的,比如es6中的箭头函数-模板字符串-promise-async/await-数组对象方法- 注意: 根据对下一代的Next版本的内部沟通,下一版本的ArkTs对类型最了更一步的限制。

vue+element ui实现图片上传并拖拽进行图片排序

vue+element ui实现图片上传并拖住进行图片排序

TypeScript基础知识:类型断言

语法,我们可以将一个值断言为特定类型或将联合类型的变量断言为其中一个类型。在实际开发中,合理使用类型断言可以提高代码的可读性和维护性。中,类型断言是一种强制将一个值视为特定类型的方式。它允许开发人员在编译时指定变量的类型,从而获得更好的类型检查和代码提示。类型断言是一种告诉编译器某个值的具体类型的方法。中的一项强大特性,它允许开发人员在编译时明确指定变量的类型,以获得更好的类型检查和代码提示。中的类型断言,并提供丰富的示例代码帮助读者更好地理解和应用这一特性。将一个联合类型的变量断言为其中一个类型。

2024年,前端必会的console骚操作

调试。程序员们努力地避免的东西,只为在代码中制造更多的错误。编写无错误的代码是即使是最好的程序员也会觉得难以实现的。这就是为什么你应该总是调试代码。而调试JavaScript代码的最好方法之一就是了不起的。除此之外,还有更好的方法。这也正是本文的重点。告诉你与控制台交互的更好方法。在复杂的IDE中输入控制台会出现各种自动补全。在Visual Studio Code中输入console时的自动补全选项。与使用普通的不同,这里有一些更好的选择。使用这些使调试过程变得更加容易和快速。

JavaScript中内置对象--数学对象

1、数学对象Math 2、日期对象new Date() 3、数组对象new Array 4、字符串对象new String()1、自定义对象(computer/car) 2、DOM对象(div/p) 3、BOM对象(window/console) 4、内置对象。

html 原生网页使用ElementPlus 日期控件el-date-picker换成中文

原生的html,加jQuery使用不习惯,新html页面导入vue3,element plus做界面,现在需要把日历上英文切成中文。elementplus, vue3对应的js都可以通过创建一个vue3项目找到对应的脚本导入)然后在node_modules对应目录的文件,把它拷贝到html项目即可。

学习调整echarts中toolbox位置toolBox工具栏属性

学习调整echarts中toolbox位置toolBox工具栏属性

OpenHarmony之消息机制实现

以上只是消息机制核外用户态的实现,最后会执行到系统调用以上的内容只是简单介绍了OpenHarmony之消息机制实现,没有具体到代码分析,移植等细节。要想成为一名鸿蒙高级开发,以上知识点是必须要掌握的,除此之外,还需要掌握一些鸿蒙应用开发相关的一些技术,需要我们共同去探索。

HarmonyOS UI框架简介

HarmonyOSUI框架是一个用于构建跨设备应用的开发框架,它属于HarmonyOS系统架构的上层框架。该框架通过提供一系列的开发模型、声明式UI范式、系统API等,帮助开发者更高效地构建用户界面。在HarmonyOSUI框架中,开发语言目前主要支持arkts/TS语言。该框架通过自研的声明式UI范式,使开发者能够描述用户界面的状态和变化,而无需关注具体的实现细节。这种范式降低了学习成本,提高了开发效率。

了解JavaScript中的基本类型值和引用类型值

/创建空对象并将其引用赋给变量avar b={};//创建空对象并将其引用赋给变量bvar c=[];//创建空数组并将其引用赋给变量c以上示例中,变量a和变量b都是指向了一个空对象,如果new Object()不传参数的话,那么用new Object()和{}来创建对象的效果是相同的。但是如果传入不同的参数,会有不同的效果。传入String 返回String,类似new String()传入Number 返回Number,类似new Number()

基于SpringBoot的校园二手闲置交易平台

基于SpringBoot的校园二手闲置交易平台的设计与实现~