当前位置:   article > 正文

【实战】学习 Electron:构建跨平台桌面应用_跨平台electron

跨平台electron


Electron 是一个流行的开源框架,允许开发者使用 JavaScript、HTML 和 CSS 等 Web 技术来构建跨平台的桌面应用程序。本文将介绍 Electron 的基本概念、优势、使用方法和实际应用案例,帮助初学者快速入门并理解如何利用 Electron 构建桌面应用程序。

一、Electron 简介

Electron 最早由 GitHub 开发,它允许开发者使用 Web 技术来构建桌面应用程序。Electron 基于 Node.js 和 Chromium,这两个都是开源项目,因此 Electron 有着丰富的生态系统和文档支持。

使用 Electron,开发者可以创建使用 HTML、CSS 和 JavaScript 构建的跨平台桌面应用程序,这些应用程序可以在 Windows、macOS 和 Linux 上运行。此外,由于 Electron 是基于 Web 技术构建的,因此开发者可以非常轻松地创建丰富的图形用户界面(GUI)。

二、Electron 的优势

1. 学习曲线平缓

由于 Electron 是基于 Web 技术构建的,因此熟悉 Web 开发的开发者可以很容易地开始使用 Electron。可以使用 HTML、CSS 和 JavaScript 来创建桌面应用程序,这些技术都是大多数 Web 开发者已经熟悉的。

2. 丰富的生态系统

Electron 有着非常丰富的生态系统,包括许多优秀的开源组件和框架,如 Electron-builder、Electron-redux 和 React-electron 等。这些组件和框架可以帮助开发者更高效地创建桌面应用程序。

3. 跨平台支持

Electron 支持 Windows、macOS 和 Linux,因此使用 Electron 可以轻松创建跨平台的桌面应用程序。这减少了开发者需要维护多个代码基础的风险,降低了开发和维护成本。

4. 开源和社区支持

Electron 是开源项目,有着庞大的社区支持。这意味着开发者可以从社区获得许多支持和资源,包括文档、示例代码、插件和模块等。此外,由于 Electron 的活跃社区,许多新功能和改进都可以及时加入到 Electron 中,为开发者提供更多选择和灵活性。

三、Electron 的使用

使用 Electron 构建桌面应用程序可以分为以下几个步骤:

1. 安装 Node.js

在开始使用 Electron 之前,需要先安装 Node.js。可以在 Node.js 官方网站上下载安装包,选择适合自己操作系统的版本进行安装。

2. 安装 Electron

可以使用 npm(Node.js 的包管理器)来安装 Electron。在命令行中输入以下命令:

npm install -g electron
  • 1

这个命令将会全局安装 Electron,使得你可以在任何地方使用它。

3. 创建项目

使用 Electron 创建一个新的项目非常简单。可以使用以下命令在命令行中创建一个新的目录,然后进入该目录:

mkdir my-electron-app && cd my-electron-app
  • 1

4. 初始化项目

可以使用以下命令初始化一个新的 Node.js 项目:

npm init
  • 1

然后根据提示输入相关信息来初始化项目。

5. 安装依赖

为了使用 Electron,需要安装一些必要的依赖。可以使用以下命令安装 Electron:

npm install --save-dev electron
  • 1

这个命令将会把 Electron 作为开发依赖添加到项目中。同时还需要安装一些其他的依赖,比如 electron-packager(用于打包应用程序)和 electron-builder(用于构建应用程序):

npm install --save-dev electron-packager electron-builder
  • 1

6. 创建主进程文件

在 Electron 中,有两个进程:主进程和渲染进程。主进程是 Node.js 进程,渲染进程是 Chromium(Electron 的 Webview 组件)。每个进程都有自己的职责和特性。在 Electron 中,主进程文件通常是 main.js 或者 main.ts。这个文件会启动一个新的主进程,并且这个主进程会加载一个 HTML 文件作为应用程序的初次视图。可以在该文件中监听 Node.js 的事件和进行 DOM 操作等。在项目中创建一个 main.js 文件:

const { app, BrowserWindow } = require('electron')
const path = require('path')
const url = require('url')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
    }
  })
  win.loadFile(path.join(__dirname, 'index.html')) // load the home page
}

app.whenReady().then(createWindow)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

7. 创建渲染进程文件

渲染进程文件是 Web 页面文件,通常使用 HTML、CSS 和 JavaScript 来编写。在 Electron 中,这个文件通常命名为 index.html。创建一个 index.html 文件,并编写一些基本的 HTML 和 CSS 以及 JavaScript 代码。以下是一个简单的示例:

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        h1 {
            color: #333;
        }
    </style>
</head>
<body>
    <h1>Hello World!</h1>
    <!-- You can use npm dependencies here -->
    <!-- <script src="path/to/your/dependency"></script> -->
    <script>
        console.log('Hello World from Electron!');
    </script>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

8. 打包应用程序

一旦创建了 Electron 应用程序的核心文件,就需要将其打包为可执行文件。可以使用 electron-packagerelectron-builder 来完成这个任务。这些工具会将 Electron 二进制文件、源代码、依赖项和 Node.js 打包在一起,生成可在目标操作系统上运行的可执行文件。例如,要使用 electron-packager 打包应用程序,可以在项目根目录下运行以下命令:

npx electron-packager . --all
  • 1

这个命令会在当前目录下创建一个打包好的应用程序。

9. 运行应用程序

在打包之前,可以在开发过程中使用以下命令启动 Electron 应用程序:

npx electron .
  • 1

这个命令将启动 Electron 应用程序,并且在开发模式下允许你使用浏览器开发者工具进行调试。

10. 调试应用程序

Electron 支持使用 Chrome DevTools 进行调试。可以在 Electron 应用程序中启用这个功能,然后使用 Chrome DevTools 进行调试。在主进程文件(例如 main.js)中添加以下代码:

const { app, BrowserWindow } = require('electron')
const path = require('path')
const url = require('url')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      devTools: true // Enable DevTools
    }
  })
  win.loadFile(path.join(__dirname, 'index.html')) // load the home page
}

app.whenReady().then(createWindow)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

然后重新运行 Electron 应用程序,你将看到一个开发者工具窗口,可以使用它来进行调试。

11. 发布应用程序

完成开发和测试后,可以将 Electron 应用程序发布到各个平台(Windows、macOS 和 Linux)。根据目标平台的要求,可以使用相应的发布工具和流程。例如,对于 Windows,可以使用 Inno Setup 或 NSIS 等工具来创建安装程序;对于 macOS,可以使用 Mac App Store 或 Sparkle 等工具来发布应用程序;对于 Linux,可以使用各个发行版的软件包管理系统来发布应用程序。这些发布流程和工具的使用方法可以参考官方文档或相关教程。

12. 拓展学习

优化应用程序性能

在 Electron 中,由于应用程序是基于 Web 技术构建的,因此 Web 技术可以优化的方面都可以在 Electron 中进行优化。例如,可以通过优化渲染性能、使用 Service Worker 进行缓存、压缩和合并静态资源等方式来提高 Electron 应用程序的性能。同时,也可以使用 Electron 提供的 API 来优化主进程和渲染进程的性能,例如使用 ipc 模块进行主进程和渲染进程之间的通信优化。

保护应用程序安全性

Electron 作为一个跨平台桌面应用程序框架,有一些安全方面的注意事项需要遵守。例如,应该避免在渲染进程中使用 Node.js 核心模块,以防止出现安全漏洞。此外,应该对从用户那里接收到的数据进行合法性验证,并避免在应用程序中使用明文密码等敏感信息。在打包应用程序时,应该使用一些工具来检测应用程序中可能存在的漏洞和恶意代码。

测试和部署应用程序

在发布 Electron 应用程序之前,应该进行充分的测试和部署。可以使用自动化测试工具来测试应用程序的功能和性能,同时可以使用持续集成和持续部署(CI/CD)工具来自动化测试和部署流程。在部署应用程序时,应该选择一个可靠的发布渠道,例如 npm、GitHub 和 Electron Store 等,这些渠道提供了完善的版本控制和发布流程。

应用程序国际化

如果你打算将应用程序推向全球市场,那么应用程序的国际化是必不可少的。Electron 提供了多种国际化(i18n)和本地化(l10n)的支持,包括对资源文件的支持,可以将字符串、日期、数字等格式根据用户的偏好设置进行转换。你可以使用 npm 包,如 i18n-jsi18n-messages 来帮助你在 Electron 应用程序中实现国际化。

使用插件扩展应用程序

Electron 允许使用插件来扩展应用程序的功能,这些插件可以从 Node.js 或者其他 Electron 应用程序中获取。你可以使用 npm 或者其他的包管理器来管理这些插件。此外,你也可以编写自己的插件,以实现特定的功能或者优化。

进行性能分析和优化

使用各种性能分析工具,比如 Chrome DevTools 的 Performance Tab,或者 Node.js 的 perf_hooks 模块,可以对 Electron 应用程序进行性能分析,找出性能瓶颈并进行优化。

与系统交互

Electron 应用程序可以与操作系统进行交互,例如打开新的浏览器窗口、接收操作系统的事件等。你可以使用 Electron 提供的模块如 shellosscreenclipboard 等来实现这些功能。

保护源代码安全

由于 Electron 是基于 JavaScript 和 HTML 等开源技术构建的,因此其源代码是可见的。为了保护源代码的安全,你可以使用混淆工具来隐藏源代码,例如 JavaScript 的压缩工具 uglify-js,或者使用 WebAssembly 等技术来编译代码。

使用 HTML5 API

Electron 应用程序可以访问许多 HTML5 API,例如 WebGL、WebRTC、WebAssembly 等。你可以使用这些 API 来增强 Electron 应用程序的功能,并为用户提供更丰富的体验。

应用程序的打包和部署

Electron 应用程序可以使用不同的工具进行打包和部署,例如 Electron-builder、electron-packager、nsis 等。你可以根据你的需求选择合适的工具,并确保在打包和部署过程中遵循最佳实践,以确保应用程序的性能和安全性。

使用 TypeScript

虽然 Electron 是基于 JavaScript 构建的,但你也可以使用 TypeScript 来编写应用程序。TypeScript 是 JavaScript 的超集,可以提供类型检查和其他功能,这可以帮助你更好地组织代码和维护应用程序的可读性和可维护性。

使用 React、Vue 或 Angular

如果你熟悉这些前端框架,那么你可以使用它们来开发 Electron 应用程序。这些框架可以帮助你更好地组织代码,并提供了丰富的组件和 API,可以让你更轻松地实现复杂的界面和交互。

实现自动化测试

为了确保应用程序的质量和稳定性,你应该考虑实现自动化测试。你可以使用工具如 Selenium、Puppeteer 或 Jest 等来进行自动化测试,以测试应用程序的不同方面,包括 UI、API、数据库等。

集成 CI/CD 流程

通过集成 CI/CD(持续集成/持续部署)流程,你可以将代码更新、构建、测试、发布等步骤自动化,从而提高开发效率并减少错误。你可以使用工具如 Jenkins、Travis CI、CircleCI 等来实现这个目标。

使用容器化技术

使用 Docker 等容器化技术,你可以将应用程序及其依赖项打包成一个可移植的容器,并在不同的环境中快速部署和运行。

进行性能优化

针对 Electron 应用程序的性能优化是必不可少的。你可以通过优化代码、使用 Web Workers、缓存等技术来提高应用程序的性能。同时,你也可以使用工具如 Lighthouse 来评估并优化应用程序的性能。

监控和错误追踪

为了及时发现并解决问题,你可以使用监控和错误追踪工具,如 Sentry、Bugsnag 或 New Relic 等。这些工具可以帮助你收集、分析应用程序的错误信息,并提供实时监控和警报功能。

自定义启动和关闭

默认情况下,Electron 应用程序在启动时会打开一个窗口,而在关闭时则会关闭所有的窗口。如果你需要自定义启动和关闭行为,你可以在主进程和渲染进程中使用事件处理函数来监听 app 对象的 readyclose 事件,并根据需要进行自定义。

使用桌面通知

Electron 允许你在用户桌面显示通知,这对于提醒用户更新应用程序或向用户显示新消息非常有用。你可以使用 Electron 的 dialog 模块中的 showNotification 方法来实现这个功能。

通过以上这些方法,你可以继续扩展 Electron 应用程序的功能、性能和安全性。同时,不断学习和实践也将帮助你成为一名更优秀的 Electron 开发者。

Electron项目开发实战

在这里插入图片描述

内容简介

《Electron项目开发实战》详细阐述了与Electron项目开发相关的基本解决方案,主要包括构建Markdown编辑器,与Angular、React和Vue集成,构建屏幕截图剪裁工具,制作2D游戏,构建音乐播放器,分析、Bug跟踪和许可机制,利用Firebase构建群聊应用程序,构建eBook编辑器和生成器,构建桌面数字钱包等内容。此外,本书还提供了相应的示例、代码,以帮助读者进一步理解相关方案的实现过程。

本书适合作为高等院校计算机及相关专业的教材和教学参考书,也可作为相关开发人员的自学用书和参考手册

作者简介

潘潇,公司高级技术经理,主要负责前端方向,同时负责跨技术栈的技术管理工作。从事前端方向8年,在前端业务研发和管理上有一定的经验。同时对其他技术方向如客户端开发等,也有不少涉猎。其中使用Electron进行夸端开发有3年,对Electron的基础知识、特性、优化及进阶使用有一定心得。

目录

1章 构建第1个Electron应用程序 1

1.1 技术需求 1

1.2 Electron是什么 1

1.3 准备开发环境 2

1.3.1 安装Visual Studio Code 2

1.3.2 针对macOS设置环境 3

1.3.3 针对Ubuntu Linux设置环境 5

1.3.4 针对Windows设置环境 6

1.3.5 在Windows上安装Node.js 7

1.4 创建一个简单的应用程序 8

1.5 多平台的打包机制 13

1.5.1 macOS包机制 13

1.5.2 Ubuntu包机制 16

1.5.3 Windows的包机制 18

1.6 本章小结 202章 构建Markdown编辑器 21

2.1 技术需求 21

2.2 配置新的项目 22

2.3 适配屏幕尺寸 26

2.4 集成应用程序菜单 28

2.4.1 创建一个自定义菜单项 29

2.4.2 定义菜单项角色 32

2.4.3 菜单分隔符 33

2.4.4 键盘加速键 35

2.4.5 特定平台的菜单 36

2.4.6 配置菜单中的应用程序名称 38

2.4.7 隐藏菜单项 39

2.4.8 进程间的消息发送 41

2.4.9 将文件保存至本地系统 46

2.4.10 从本地系统中加载文件 53

2.4.11 创建一个文件菜单 57

2.5 添加拖曳功能 59

2.6 支持自动更新功能 62

2.7 修改应用程序的标题 71

2.8 本章小结 723章 与Angular、React和Vue集成 73

3.1 技术需求 73

3.2 利用Angular构建Electron应用程序 73

3.2.1 生成Angular项目 74

3.2.2 将Angular项目与Electron集成 76

3.2.3 配置实时重载 81

3.2.4 设置生产版本 83

3.2.5 设置条件加载 85

3.2.6 使用Angular Material组件 87

3.2.7 Anguar路由机制 91

3.3 利用React构建Electron应用程序 98

3.3.1 创建React项目 98

3.3.2 实时重载 102

3.3.3 设置产品发布版本 105

3.3.4 设置条件加载 107

3.3.5 使用Blueprint UI工具箱 108

3.4 利用Vue.js构建Electron应用程序 113

3.4.1 创建一个Vue配置文件 117

3.4.2 实时重载 119

3.4.3 产品发布版本 121

3.4.4 设置条件加载 122

3.4.5 添加路由机制 123

3.4.6 配置Vue Material 125

3.5 本章小结 1294章 构建屏幕截图剪裁工具 131

4.1 技术需求 131

4.2 准备项目 132

4.3 配置无框窗口 133

4.3.1 macOS的附加选项 135

4.3.2 使用隐藏的titleBarStyle 135

4.3.3 titleBarStyle属性的hiddenInset值 136

4.3.4 titleBarStyle的customButtonsOnHover值 137

4.4 透明窗口 138

4.5 可拖曳的应用程序窗口 141

4.6 添加截图工具栏按钮 142

4.7 使用desktopCapturer API 144

4.8 计算主显示尺寸 145

4.9 生成并保存缩略图 146

4.10 重置图像尺寸并剪裁图像 148

4.11 测试应用程序的行为 151

4.12 集成系统托盘 152

4.13 启动时隐藏主应用程序菜单 154

4.14 注册全局键盘快捷方式 155

4.15 本章小结 1575章 制作2D游戏 159

5.1 技术需求 159

5.2 配置游戏项目 160

5.3 运行Hello World示例 163

5.4 渲染背景图像 166

5.5 禁止窗口尺寸变化 168

5.6 渲染精灵对象 168

5.7 缩放精灵对象 169

5.8 处理键盘输入 171

5.9 根据方向翻转飞船对象 173

5.10 控制精灵对象的坐标 174

5.11 控制精灵对象的速度 177

5.12 本章小结 1796章 构建音乐播放器 181

6.1 技术需求 181

6.2 创建项目 182

6.3 音乐播放器组件 184

6.3.1 下载音乐文件 185

6.3.2 基本的播放器设置 188

6.3.3 样式按钮 192

6.4 播放控制按钮 195

6.4.1 Stop按钮 195

6.4.2 静音和非静音按钮 197

6.4.3 音量按钮 199

6.5 实现歌曲的进度栏 202

6.6 显示音乐元数据 203

6.7 改进用户界面 208

6.8 最终的结构 210

6.9 本章小结 2137章 分析、Bug跟踪和许可机制 215

7.1 技术需求 215

7.2 连接分析和跟踪机制 216

7.3 构建自身方案或使用已有服务 216

7.3.1 创建自己的分析服务 217

7.3.2 使用第三方分析服务 217

7.4 针对Electron应用程序使用Nucleus 218

7.5 创建一个新的Nucleus账户 219

7.6 创建基于跟踪支持的新项目 222

7.7 安装Nucleus Electron库 224

7.8 查看实时分析数据 226

7.9 禁用每个用户请求的跟踪机制 230

7.10 验证实时用户统计结果 231

7.11 支持离线模式 232

7.12 处理应用程序更新 232

7.13 加载全局服务器设置 235

7.14 许可检查机制和政策 237

7.14.1 创建新策略和许可 237

7.14.2 检查应用程序中的证书 240

7.15 本章小结 2418章 利用Firebase构建群聊应用程序 243

8.1 技术需求 243

8.2 创建一个Angular项目 245

8.3 创建新的Firebase账户 248

8.4 创建一个Firebase应用程序 252

8.5 配置Angular Material组件 254

8.5.1 添加Browser Animations模块 255

8.5.2 配置默认的主题 255

8.5.3 添加Material Icons库 255

8.5.4 添加导航栏 256

8.5.5 利用材质工具栏测试应用程序 257

8.6 构建登录对话框 258

8.6.1 实现Material界面 259

8.6.2 错误处理机制 261

8.6.3 准备聊天组件占位符 262

8.7 将登录对话框连接至Firebase Authentication 263

8.7.1 启用注册供应商 264

8.7.2 创建示例账户 266

8.7.3 集成Login对话框和Firebase 268

8.8 配置实时数据库 271

8.9 渲染聊天群列表 275

8.10 实现群消息页面 279

8.11 显示群消息 281

8.12 发送群消息 285

8.12.1 更新消息列表界面 288

8.12.2 进一步改进 288

8.13 验证Electron Shell 289

8.14 本章小结 2909章 构建eBook编辑器和生成器 291

9.1 技术需求 291

9.2 创建项目结构 292

9.2.1 生成新的React应用程序 292

9.2.2 安装编辑器组件 293

9.2.3 测试Web应用程序 298

9.2.4 与Electron Shell集成 300

9.3 升级代码并使用React Hooks 301

9.4 控制键盘快捷方式 302

9.4.1 加载文件 303

9.4.2 保存文件 306

9.5 集成应用程序菜单 308

9.6 设置电子书生成器 311

9.6.1 安装Docker 312

9.6.2 运行Pandoc容器 315

9.6.3 将文档发送至主进程(Node.js) 317

9.7 从Electron中调用Docker命令 320

9.7.1 将标记文本发送至Node.js进程 320

9.7.2 将标记文本保存至本地磁盘 320

9.8 生成PDF电子书 323

9.9 生成ePub电子书 325

9.10 本章小结 32810章 构建桌面数字钱包 329

10.1 技术需求 329

10.2 利用React生成项目 330

10.3 集成Ant Design库 332

10.4 设置个人以太坊区块链 334

10.5 配置Ethereum JavaScript API 338

10.6 显示以太坊节点信息 340

10.6.1 获取节点信息 340

10.6.2 在Header中渲染节点信息 341

10.7 集成应用程序菜单 342

10.8 渲染账户列表 344

10.9 显示账户余额 347

10.10 将以太转至另一个账户中 350

10.11 打包应用程序并发布 355

10.12 本章小结 358
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/388152
推荐阅读
相关标签
  

闽ICP备14008679号