打造一个有点好看的 uniapp 网络测速软件

news/2025/2/20 14:34:55

大家好,我是一名前端小白。今天想和分享一个有点好看的网络测速 uniapp 组件的实现过程。这个组件不仅外观精美,而且具有完整的功能性,是一个非常适合学习和实践的案例。

设计理念

在开始coding之前,先聊聊设计理念。一个好的测速工具应该具备以下特点:

  1. 直观的速度显示
  2. 清晰的测试过程
  3. 完整的设备信息
  4. 优雅的交互体验

基于这些考虑,将整个界面分为四个主要部分。下面让一步步实现这个组件。

1. 速度显示面板 - 视觉核心

速度显示面板是整个组件最吸引眼球的部分。我选择了圆形设计,因为圆形给人一种仪表盘的感觉,非常符合测速工具的定位。

<template>
  <view class="speed-panel">
    <view class="speed-circle" :class="{ 'testing': isTesting }">
      <view class="speed-content">
        <text class="speed-value">{{ isFirst ? "点击开始" : (downloadSpeed ? (downloadSpeed * 1024).toFixed(0) : '...') }}</text>
        <text class="speed-unit">{{ isFirst ? "" : "kb/s" }}</text>
      </view>
      <view class="speed-wave"></view>
    </view>
  </view>
</template>

在样式设计上,使用了现在非常流行的新拟态(Neumorphism)设计风格:

.speed-circle {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background: linear-gradient(145deg, #ffffff, #f0f0f0);
  box-shadow: 20px 20px 60px #d1d9e6, -20px -20px 60px #ffffff;
  position: relative;
  overflow: hidden;
}

这里有个小技巧:通过设置两个方向的阴影,一个深色一个浅色,创造出了非常漂亮的立体效果。而当测速开始时,会显示一个波浪动画,这给用户一种动态的反馈:

@keyframes wave {
  0% { transform: translateY(100%); }
  100% { transform: translateY(-100%); }
}

.speed-wave {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(0deg, rgba(66, 153, 225, 0.1) 0%, rgba(66, 153, 225, 0) 50%);
  animation: wave 2s infinite linear;
}

2. 信息卡片 - 设备信息一目了然

信息卡片区域采用了现代化的卡片设计。使用Flex布局来实现响应式的排列,这样在不同尺寸的屏幕上都能很好地展示:

<template>
  <view class="info-cards">
    <view class="info-card">
      <view class="card-icon">📱</view>
      <view class="card-content">
        <text class="card-title">设备信息</text>
        <text class="card-detail">{{ phoneBrand }} {{ phoneModel }}</text>
      </view>
    </view>
  </view>
</template>

样式上追求简洁但不失细节:

.info-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  margin: 20px 0;
}

.info-card {
  flex: 1;
  min-width: 150px;
  background: white;
  padding: 15px;
  border-radius: 16px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
}

在这里插入图片描述

这里的flex-wrap: wrap属性确保了在窄屏设备上卡片会自动换行,gap属性则提供了卡片之间优雅的间距。

3. 测速核心逻辑 - 性能与准确性的平衡

测速的核心是通过计算下载固定大小文件所需的时间来得出网速。这里选择了Cloudflare的测速API,它可以提供稳定的测试环境:

Cloudflare 测速 API 的基本格式如下:

https://speed.cloudflare.com/__down?bytes={size}

其中:

  • speed.cloudflare.com 是 Cloudflare 的测速服务器
  • __down 表示下载测试
  • bytes 参数指定要下载的文件大小(以字节为单位)
  1. bytes(必需)

    • 类型:整数
    • 范围:1 到 1073741824(1GB)
    • 示例:bytes=10485760(10MB)
  2. 其他可选参数

    https://speed.cloudflare.com/__down?bytes=10485760&duration=10
    
    • duration:测试持续时间(秒)
    • throughput:限制下载速度(字节/秒)

搞一个 10 M 的文件大小,并使用 uni.downloadFile 下载该文件

methods: {
  testDownloadSpeed() {
    const fileSize = 10 * 1024 * 1024; // 选择10MB作为测试文件大小
    const url = `https://speed.cloudflare.com/__down?bytes=${fileSize}`;
    const startTime = Date.now();

    // 开始下载测试
    uni.downloadFile({
      url,
      success: () => {
        const duration = (Date.now() - startTime) / 1000;
        const speedMB = (fileSize / (1024 * 1024)) / duration;
        this.downloadSpeed = speedMB.toFixed(2);
        
        // 转换为Mbps以计算带宽等级
        this.bandwidth = (speedMB * 8).toFixed(2);
      }
    });
  }
}

为了提供更好的用户体验,在测试过程中添加了进度提示:

// 模拟进度更新
const progressInterval = setInterval(() => {
  if (this.progress < 90) {
    this.progress += 5;
  } else {
    clearInterval(progressInterval);
  }
}, 200);

4. 进度条设计 - 动态反馈的艺术

进度条的设计看似简单,但要做好也需要注意很多细节:

<template>
  <view class="progress-wrapper" v-if="isTesting">
    <view class="progress-bar">
      <view class="progress-fill" :style="{ width: progress + '%' }"></view>
    </view>
    <text class="progress-text">{{ progress }}%</text>
  </view>
</template>

样式上使用渐变色来增加视觉效果:

.progress-bar {
  width: 100%;
  height: 8px;
  background: #e2e8f0;
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #4299e1, #3182ce);
  transition: width 0.3s ease;
}

在这里插入图片描述

transition属性确保了进度条的平滑动画效果,给用户更好的视觉体验。

5. 带宽等级计算 - 数据的智能解读

为了让测试结果更有意义,简单添加了带宽等级的计算功能:

computed: {
  getBandwidthCategory() {
    if (this.downloadSpeed) {
      const speedMbps = this.downloadSpeed * 8;
      // 根据实际速度返回对应的带宽等级
      if (speedMbps <= 10) return "10M宽带";
      else if (speedMbps <= 20) return "20M宽带";
      else if (speedMbps <= 50) return "50M宽带";
      else if (speedMbps <= 100) return "100M宽带";
      else if (speedMbps <= 200) return "200M宽带";
      else if (speedMbps <= 500) return "500M宽带";
      else return "1000M宽带以上";
    }
    return '正在测试...';
  }
}

实现要点与技术总结

  1. UI设计

    • 采用新拟态设计风格
    • 使用CSS渐变和阴影创造立体感
    • 响应式布局适配各种屏幕
  2. 动画效果

    • 波浪动画提供视觉反馈
    • 进度条平滑过渡
    • 状态切换动画
  3. 性能优化

    • 使用computed属性处理复杂计算
    • 合理的防抖处理
    • 优化重绘性能
  4. 用户体验

    • 清晰的测试状态提示
    • 直观的数据展示
    • 平滑的动画过渡

结语

感谢阅读!


http://www.niftyadmin.cn/n/5858140.html

相关文章

TCP通讯-客户端链接

一、TCP客户端 效果展示 二、准备任务 1.创建画面 2. 创建服务端&#xff0c;与客户端进行相连接 三、控件的分体效果 1.窗体加载 private void Form1_Load(object sender, EventArgs e){System.Diagnostics.Process.Start("D:\17_SocketTool\SocketTool.exe");} 2.…

MySQL数据库(3)—— 表操作

目录 一&#xff0c;创建表 1.1 创建表的SQL 1.2 演示 二&#xff0c;查看表 三&#xff0c;修改表 四&#xff0c;删除表 常用的表操作会涉及到两种SWL语句 DDL&#xff08;Data Definition Language&#xff09;数据定义语言&#xff1a;建表、改表、删表等&#xff0…

上位机知识篇---与、或、移位操作(、|、>><<)

文章目录 前言第一部分&#xff1a;与操作&#xff08;&&#xff09;简介语法示例在代码中的应用1.提取某一位2.屏蔽某些位&#xff08;清零&#xff09;3.判断某一位是否为 1 在 DS18B20 和 AT24C02 代码中的应用1.DS18B20 代码2.AT24C02 代码 第二部分&#xff1a;移位操…

STM32 定时器产生定周期方法

目录 背景 程序 第一步、使能PCLK1外设时钟​编辑 第二步、时基单元配置 第三步、配置NVIC&#xff08;设置定时中断优先级&#xff09;​编辑 第四步、使能溢出中断 第五步、使能定时器 第六步、填写中断处理函数&#xff08;ISR&#xff09; 背景 在单片机开发当中&…

[AI相关]Unity的C#代码如何简写

是一个某培训机构的飞行棋教学源码 不知道&#xff0c;是否有人想知道怎么可以简写 &#xff08;这个问AI&#xff0c;DeepSeek也应该找不到答案的&#xff09; 静态变量 属性引用 单例 注入 一些UnityEvent特性就不说了。。。 IL 注入 运算符号改写

Linux第一章 环境搭建

文章目录 环境搭建安装wsl安装GUI可视化界面 常用命令基础常识命令解析器查看shell操作系统结构目录结构主要目录介绍 路径结构绝对路径相对路径 命令提示符文件属性 包管理命令sudo apt-get 文件和目录操作treelscdpwdwhichtouchmkdirrmdirrmcpmvcatmorestatlnwcwhoami 用户权…

STM32的HAL库开发---单通道ADC采集实验

一、实验简要 1、功能描述 通过ADC1通道1&#xff08;PA1&#xff09;采集电位器的电压&#xff0c;并显示ADC转换的数字量及换算后的电压值 2、确定最小刻度 VREF 3.3V ---》 0V ≤ VIN ≤ 3.3V ---》最小刻度 3.3 / 4096 &#xff0c;F1的分辨率是12位的&#xff0c;也…

cmake:定位Qt的ui文件

如题。在工程中&#xff0c;将h&#xff0c;cpp&#xff0c;ui文件放置到不同文件夹下&#xff0c;会存在cmake找不到ui文件&#xff0c;导致编译报错情况。 cmake通过指定文件路径&#xff0c;确保工程找到ui文件。 标识1&#xff1a;ui文件保存路径。 标识2&#xff1a;添加…