评论
前端噩梦,uni-app当选项卡在页面中间如何处理点击后闪屏

前端噩梦,uni-app当选项卡在页面中间如何处理点击后闪屏

河流之所以让人如此平静,是因为它没有任何疑虑,一定会到达它要去的地方,而且它不想去任何其他地方。 ---艾伦·亚历山大·米恩-

前端噩梦,uni-app当选项卡在页面中间如何处理点击后闪屏

最早星宿UI导航栏也是在中间,因为无法处理点击请求数据后,页面重新渲染高度丢失导致闪屏问题,后续灵沐因为采用点击滚动页面方式,可以缓解之外 ,今天采用最简单的补一个占位符方式

 缘由

当我们滑动页面点击选项卡,需要重新发送请求渲染数据,不同选项卡内容不同因此的先清空之前的内容在渲染;

数据清空也会让容器高度丢失,高度已丢失页面就会往下跌落;这就是前端噩梦,当选项卡在页面中间点击后闪屏的原因

前端噩梦,uni-app当选项卡在页面中间如何处理点击后闪屏

解决

我们明白页面闪屏是因为内容高度丢失,我们只要给他补充一个有高度的容器即可

容器的高度可以直接固定一个1000rpx之类的都可,或者动态获取屏幕高度赋值给容器

最后只要思考容器什么时候出现,什么时候关闭;点击选择卡之后重新渲染内容,这时候数据空了,显示占位容器,请求接口得到数据后在隐藏容器

效果图

适用于:选项卡在页面中间,基础教程,最简单的思路;基于UNI-app

前端噩梦,uni-app当选项卡在页面中间如何处理点击后闪屏

案例

<template>

<view class="container">

<!-- 顶部红色背景容器 -->

<view class="top-container">

<text class="top-title">测试案例</text>

</view>



<!-- 选项卡 -->

<view class="tabs">

<view :class="currentTab == 0 ? 'active tab-item' : 'tab-item'" @click="switchTab(0)">

				文章

</view>

<view :class="currentTab == 1 ? 'active tab-item' : 'tab-item'" @click="switchTab(1)">

				新闻

</view>

</view>



<!-- 内容区域 -->

<view class="content">

<!-- 内容列表 -->

<view class="news-list">

<view class="news-item" v-for="(item, index) in newsList" :key="index">

<image class="news-img" :src="item.imgUrl"></image>

<view class="news-info">

<text class="news-title">{{item.title}}</text>

<text class="news-desc">{{item.desc}}</text>

<text class="news-time">{{item.time}}</text>

</view>

</view>

</view>



<!-- 占位符 -->

<view v-if="tapHeight" style="height: 800px;"></view>

</view>

</view>

</template>



<script>

export default {

data() {

return {

tapHeight:false,



currentTab: 0, // 当前选中的选项卡

newsList: [], // 新闻列表数据

page: 1, // 当前页码

pageSize: 10, // 每页数量

// 模拟数据

mockData: [{

title: "这是一篇文章标题",

desc: "这是文章的简要描述内容,一般会显示前几句...",

time: "2025-05-10",

imgUrl: "https://picsum.photos/200/150?random=1"

					},

					{

title: "科技创新引领未来发展",

desc: "随着科技的不断进步,人工智能、大数据等新技术正在改变我们的生活...",

time: "2025-05-09",

imgUrl: "https://picsum.photos/200/150?random=2"

					},

					{

title: "健康生活小常识",

desc: "合理饮食、适量运动是保持健康的关键,这里有一些实用的健康小知识...",

time: "2025-05-08",

imgUrl: "https://picsum.photos/200/150?random=3"

					},

					{

title: "全球经济形势分析",

desc: "当前全球经济面临诸多挑战,贸易摩擦、通货膨胀等问题影响着各国经济...",

time: "2025-05-07",

imgUrl: "https://picsum.photos/200/150?random=4"

					},

					{

title: "教育改革新动态",

desc: "教育部门近日发布了一系列教育改革措施,旨在提高教育质量...",

time: "2025-05-06",

imgUrl: "https://picsum.photos/200/150?random=5"

					},

					{

title: "环保行动,从我做起",

desc: "环境污染问题日益严重,每个人都应该为环保出一份力...",

time: "2025-05-05",

imgUrl: "https://picsum.photos/200/150?random=6"

					},

					{

title: "文化艺术展览活动",

desc: "近期将有多个重要的文化艺术展览在本市举行,丰富市民文化生活...",

time: "2025-05-04",

imgUrl: "https://picsum.photos/200/150?random=7"

					},

					{

title: "体育赛事精彩回顾",

desc: "上周末的足球比赛精彩纷呈,主队以3:1战胜对手...",

time: "2025-05-03",

imgUrl: "https://picsum.photos/200/150?random=8"

					},

					{

title: "美食探店:发现城市美味",

desc: "今天带大家探访一家隐藏在小巷子里的特色餐厅,味道令人惊艳...",

time: "2025-05-02",

imgUrl: "https://picsum.photos/200/150?random=9"

					},

					{

title: "旅游攻略:最佳出行目的地",

desc: "五一假期即将到来,这里为您推荐几个适合出行的旅游胜地...",

time: "2025-05-01",

imgUrl: "https://picsum.photos/200/150?random=10"

					}

				]

			}

		},

onLoad() {

// 页面加载时初始化数据

this.loadData();

		},

methods: {

// 切换选项卡

switchTab(index) {

this.tapHeight = true;//显示占位符



this.currentTab = index;

this.newsList = [];

this.loadData();

			},



// 加载数据

loadData() {

// 模拟网络请求延迟

setTimeout(() => {

// 生成30条模拟数据

let mockType = this.currentTab === 0 ? '文章' : '新闻';

let newData = [];



for (let i = 0; i < this.pageSize; i++) {

// 随机选择一条基础数据进行修改

let randomIndex = Math.floor(Math.random() * this.mockData.length);

let item = JSON.parse(JSON.stringify(this.mockData[randomIndex]));



// 修改标题以区分文章和新闻

						item.title = `${mockType} ${this.page * this.pageSize + i + 1}: ${item.title}`;

						newData.push(item);



this.tapHeight = false;//关闭占位符

					}



this.newsList = [...this.newsList, ...newData];

this.page++;



// 判断是否还有更多数据

if (this.newsList.length >= 30) {

this.hasMore = false;

					}

				}, 500);

			},





		}

	}

</script>



<style>

.container {

margin: 28rpx;

	}



.top-container {

height: 400rpx;

background-color: #ff0000;

display: flex;

align-items: center;

justify-content: center;

margin-bottom: 28rpx;

	}



.top-title {

color: #ffffff;

font-size: 48rpx;

font-weight: bold;

	}



.tabs {

display: flex;

height: 88rpx;

line-height: 88rpx;

background-color: #ffffff;

border-bottom: 1rpx solid #eeeeee;

	}



.tab-item {

flex: 1;

text-align: center;

font-size: 32rpx;

color: #333333;

	}



.active {

color: #ffffff;

background-color: #000000;

font-weight: bold;

	}



.content {

padding: 20rpx;

	}



.loading {

height: 100rpx;

display: flex;

align-items: center;

justify-content: center;

color: #999999;

font-size: 28rpx;

	}



.news-list {

background-color: #ffffff;

border-radius: 12rpx;

	}



.news-item {

display: flex;

padding: 24rpx;

border-bottom: 1rpx solid #f5f5f5;

	}



.news-img {

width: 200rpx;

height: 150rpx;

border-radius: 8rpx;

object-fit: cover;

	}



.news-info {

flex: 1;

margin-left: 20rpx;

display: flex;

flex-direction: column;

justify-content: space-between;

	}



.news-title {

font-size: 32rpx;

color: #333333;

font-weight: 500;

line-height: 40rpx;

display: -webkit-box;

		-webkit-box-orient: vertical;

		-webkit-line-clamp: 2;

overflow: hidden;

	}



.news-desc {

font-size: 28rpx;

color: #666666;

line-height: 36rpx;

display: -webkit-box;

		-webkit-box-orient: vertical;

		-webkit-line-clamp: 1;

overflow: hidden;

margin-top: 8rpx;

	}



.news-time {

font-size: 24rpx;

color: #999999;

margin-top: 8rpx;

	}



.load-more {

height: 88rpx;

line-height: 88rpx;

text-align: center;

color: #666666;

font-size: 28rpx;

	}



	page {

background-color: #f8f8f8;

	}

</style>