TML 基础
非常简单的HTML文档
HTML 标题
HTML 段落
HTML 链接
HTML 图片
实例解析
HTML 标题
HTML 标题
在html源码中插入注释
插入水平线
实例解析
HTML 段落
HTML 段落
更多段落
本例演示在 HTML 文档中折行的使用。
HTML 格式化的某些问题。
实例解析
HTML 文本格式化
文本格式化
此例演示如何使用 pre 标签对空行和空格进行控制。
此例演示不同的"计算机输出"标签的显示效果。
此例演示如何在 HTML 文件中写地址。
此例演示如何实现缩写或首字母缩写。
此例演示如何改变文字的方向。
此例演示如何实现长短不一的引用语。
文本下划线与删除线
实例解析
HTML 样式
HTML Style 元素
背景色样式
字体样式,颜色,大小
文本对齐样式
设置文本字体
设置文本字体大小
设置文本字体颜色
设置文本字体,字体大小,字体颜色
HTML使用不同样式
没有下划线的链接
链接到一个外部样式表
实例解析
HTML 链接
创建超级链接
将图像作为链接
在新的浏览器窗口打开链接
链接到同一个页面的不同位置
跳出框架
创建电子邮件链接
创建电子邮件链接 2
实例解析
HTML 图像
插入图像
从不同的位置插入图片
排列图片
本例演示如何使图片浮动至段落的左边或右边。
制作图像链接
创建图像映射
实例解析
HTML 表格
简单的表格
没有边框的表格
表格中的表头
带有标题的表格
跨行或跨列的表格单元格
表格内的标签
单元格边距(Cell padding)
单元格间距(Cell spacing)
实例解析
HTML 列表
无序列表
有序列表
不同类型的有序列表
不同类型的无序列表
嵌套列表
嵌套列表 2
定义列表
实例解析
HTML Forms 和 Input
创建文本域(Text fields)
创建密码域
复选框
单选按钮
简单的下拉列表
预选下拉列表
本例演示如何创建一个文本域(多行文本输入控件)。
创建一个按钮
本例演示如何在数据周围绘制一个带标题的框。
带有文本域与输入域的表单
带有复选框与提交按钮的form表单
带有单选框与提交按钮的表单
发送邮件表单
实例解析
HTML iframe
内联框架 (HTML页面中插入框架)
实例解析
HTML 头部元素
描述了文档标题
HTML页面中默认的URL链接
提供文档元数据
实例解析
HTML 脚本
插入一个脚本
使用 <noscript> 标签
实例解析
如您还有不明白的可以在下面与我留言或是与我探讨QQ群308855039,我们一起飞!
章作者分享了一种基于设备模板的移动端原型设计方法,相信能够对你的原型设计工作带来帮助,值得马克。
在使用Axure设计移动端原型的应用方面,我总结出了两种常用的方法。第一种是更适合在移动端进行演示的设计方法,大家可以参考我之前已经分享过的一篇教程:使用Axure打造最佳的移动端交互原型教程,使用这种方法输出的原型在手机设备上进行演示时可以达到跟真实APP几乎一致的展示效果及交互体验。在今天我将分享另外一种基于设备模板的移动端原型设计方法。
什么是基于设备模板的移动端原型设计方法?简而言之就是在Axure的编辑界面中放置对应的机型模板,使输出的原型达到更规范和真实的演示效果。其实这是一种很常见的移动端原型的设计方法,很多同行在设计原型的时候也都用过。这篇分享教程将对个设计方法进行了总结和梳理,并基于这个方法制作了一套可快速复用的模板。这套模板具有几个方面的特点:
● 结构化,根据APP界面结构进行搭建;
● 标准化,非常方便进行编辑和维护;
● 高保真,可高度还原移动端交互效果;
在本篇分享的结尾我会提供模板的Axure源文件下载,其中包含了最新的IPhoneX和IPhone8等多套IOS设备机型,以及一些常见的界面元素和交互效果。在开始正式的介绍之前,大家可以查看使用这套模板还原IOS中两款官方应用的设计演示。
由于这套模板是基于IOS系统进行设计的,所以相关界面元素和交互方式均以IOS为标准。目前主流的移动端系统除了IOS还有Android,这两种系统设计标准和交互方式其实是存在一些差异的,不过目前市面上大部分APP在设计时并没有争对两种系统做单独的处理。
所以如果没有特珠需求的话,我们一般也只需要输出一套原型方案就可以了,不过设计过程中需要尽量兼顾这两个主流的系统。当然,如果你的产品明确需要按照Android的系统规范来设计,你也可以参照本教程设计一套Android的原型模板,相关交互方式可以参照Android版的交互指南规范。
在开始介绍模板的搭建和使用方法之前,需要先对APP的界面结构做一个简单的介绍,熟悉了界面结构可以方便我们后续的设计。常见APP的界面主要由以下元素或组件组成:
状态栏显示设备的关键信息,包含设备模型或网络提供商、网络信号强度、电池使用量、时间等。在特殊界面中可以对状态栏做隐藏处理,或根据需要自定义状态栏背景。
导航栏位于app内容区的上方,系统状态栏的下方,并且提供在一系列页面中的导航能力。可在导航栏中显示当前视图的标题,如果标题非常冗长且无法精简,可以空缺,避免用过多的元素填满导航栏。导航栏中可以添加文字和图标控件,相关控件的可点击区域需要大于控件的可视大小。
内容区域根据需要进行自定义设计,常见的设计形式有菜单列表、图标列表、卡片列表、图文组合等。
标签栏位于APP底部,方便用户在不同功能模块之间进行快速切换。标签栏一般用作APP的一级分类,数量控制在3-5个之间。建议使用Badge进行提示,让用户知道有内容更新。
工具栏一般会出现在视图的的底部,提供给用户相关可操作的功能按纽。如,邮件应用程序里的收件箱栏中有删除、分享、答复等等。
移动端的弹出层根据弹出方式不同,共分为模态窗口、动作面板、弹出面板等几种不同的类型。在实际使用中,可根据界面的交互方式选择对应的类型。
一种轻量级反馈提示,可以用来显示不会打断用户操作的内容,适合用于页面转场、数据交互的等场景中。一次只显示一个轻提示,有图标的提示字数为4-6个,没有图标的轻提示字数不宜超过14个。
列表视图是移动端APP中一种通用的界面元素。很多应用程序在一定程度上,都有使用表视图来显示数据列表。常见的例如IOS的联系人应用中联系人信息列表,另外还有Mail中使用列表视图显示邮箱和邮件。列表视图不仅可以用来显示文本数据,也可以用来呈现图像数据。
以上是豆瓣APP的一个界面截图示例,界面的结构用颜色进行了区分,从上至下分别为:状态栏、导航栏、内容区、标签栏。
在介绍完APP的界面结构之后,接下来说明一下模板的搭建方法。在本篇教程的结尾会提供了已经制作好的模板的文件,大家可以下载并参考本部分介绍进行使用,也可以参照介绍制作自己的原型模板。
在制作模板时需要用到对应的机型设备的图片素材,可以通过Dribbble等设计分享平台找到对应的素材文件,然后对素材做一些简单的处理。处理的过程首先是去掉多余的元素,只保留机型设备的框架图片。另外还需要对图片的尺寸进行调整,例如在制作手机等移动端模板时我们将内容区域定为375px,需要根据所定的内容区域对图片的尺寸进行相应的调整。
为什么模板的内容区域是375px?这个问题我在上篇教程中进行过介绍,所以不再进行展开说明。但是需要记住的这个尺寸是一个重要的标准,后续在设计过程中相关元件的宽度尺寸都需要参照这个标准。机型设备的图片素材准备好之后,我们在Axure中创建一个对应的母版,然后将机型设备图片拖入到母版中。母版的名称可以按该机型设备的名称命名,后面在使用时在新建的页面中拖入该母版即可。
下一步需要创建前面介绍过的APP界面中常见元素或组件,首先大家可以看一下这张图片中已经创建好的模板,其中包含了机型母版、轻提示、弹层、导航栏、标签栏、内容框架等元素。
在这个模板页面的概要视图中可以看到相关的对象,所有对象我都创建了一个对应的动态面板。这样的处理主要出于两个方面的考虑,一是方便对相关元素进行编辑维护,二是相关对象的显示是有顺序的,这样可以方便在概要视图中进行排序处理。
界面的主要内容在内容框架动态面板中进行编辑和维护,由于该动态面板设置了自动显示滚动条,如果你的界面内容超出了一屏,在演示时可以通过在内容框架区域滚动鼠标滚轮查看更多内容。
模板中的界面元素的尺寸并没有非常严格的标准,以下尺寸是我根据比例进行设置的,仅供参考。IphoneX状态栏:44px、IphoneX标签栏:80px、Iphone8状态栏:28px、IphoneX标签栏:60px、导航栏:40px。另外,内容区域的高度因为机型设备的素材图片不统一可能略有差异,基本上可以忽略。
在设计原型时建议每一个界面创建一个对应的页面,通过添加页面链接进行界面跳转,这样方便对原型进行编辑和维护。不建议将多个界面用动态面板堆砌在一起页面内,这样会使输出的原型在演示时出现卡顿现象。
在概要视图中可以看到相关元素对应动态面板的层级顺序,在使用该模板的时候请尽量参照此顺序,否则可能在演示时出现显示错误的情况。
为了方便维护可以将标签栏创建为母版,然后添加到需要显示标签栏的页面中。另外,在对应的页面中需要显示对应的标签选中效果,只需要在该页面中的标签栏动态面板中添加一个选中效果的标签元件。
如果页面中添加了标签栏或工具栏,由于标签页的动态面板在内容框架的动态面板之上,在演示时会出现内容有一部分被挡住的情况。可以创建一个高度为100px的热区元件为母版,将母版拖入对应的页面底部,用来解决内容区域被挡住的问题。
经常有朋友向我咨询如何设计出更漂亮美观的原型,虽然原则上原型能完整的体现出需求细节即可,好看并不是我们在原型输出时应该关注的重点,但是如果能满足说明需求的同时能把原型做得更漂亮一些更好,这也算是体现专业程度和工作态度的一个方面,而且很多人对自己的输出物也是有强烈的美感追求的。
其实原型设计不需要了解太复杂的设计方法,只要掌握一点简单的技巧就能达到美观的效果,同时能让整体更统一和标准。在分享的这套模板中包含了一些基本的设计元素,我下面对其中的一些规范细节进行说明,供大家进行参考。
Axure中的配色板提供了一些常用的颜色色值,可用作一些常用元素的颜色配色。例如截图中标注1中的纵向的灰色色值可用于相关字体元素的颜色,标注2中横向的灰色色值可用于相关元素的背景和线条的颜色。另外,点击标注3中的更多按纽,可以将其它的常用色值加入到自定义颜色中,方便快速的使用。
在以前的教程中已经介绍过辅助线的使用方法,合理的使用辅助线可以帮助我们提升设计效率,同时能让输出的原型效果更标准,所以强烈建议大家在设计过程中使用。以下是模板中内容框架编辑区域的截图,是我常用使用辅助线用来排版的方式。截图中的辅助线均为横向x轴辅助线,可以看到其中共有4条,分别介绍一下它们的作用和位置:
这些辅助线的用法只是作为参考,可以根据自己的需要新建对应的辅助线。鼠标光标移动到编辑区域的左侧和顶部的标尺区域,按住鼠标左键并往编辑区域拖动时,就可以生成横向x轴或纵向y轴的辅助线,然后将辅助线拖动到对应的位置即可。辅助线还有一个特性就是当拖动元件靠近它时,元件会自动吸附到辅助线的边缘达到快速对齐的效果。
移动端原型中最常用的交互效果就是弹出层和轻提示两种,模板中已经包含了这种两交互效果的相关元件和事件,这里再单独简单的介绍一下。
在模板页面的概要视图中可以看到名为“提示”的动态面板,需要显示的提示信息在这个动态面板中编辑就可以了。当前的动态面板中有一个“操作成功”的提示状态,如果在一个页面中显示多个提示,可以新增对应的状态然后修改相关的提示内容。
选中提示的动态面板的状态右击选择复制状态可以快速创建新的提示。建议对每个对应的提示状态进行命名,这样方便后续进行管理。关于轻提示的基本使用规范请参照前面的介绍内容。
Toast提示的显示方式设置很简单,只需要在对应的元件事件上加入以上的交互动作。首先设置提示动态面板中对应的状态,然后设置显示动态面板,显示时有一个逐渐的动画效果。
Toast提示显示以后会在3秒后自动逐渐隐藏,模板中的这个交互动作已经加在提示动态面板的显示时事件中了,不需要再单独的进行设置。
移动端的弹层共分为模态窗口、动作面板、弹出面板等几种不同的类型。在模板页面的概要视图中可以看到名为“弹层”的动态面板,可以根据需要创建更多其它的弹层状态,还能在对应的面板状态属性中设置透明背景的遮罩效果。
上面截图中的为比较常见的模态窗口弹层效果,设置方式是在对应的元件事件上加入以上的交互动作。另外,根据模态窗口、动作面板、弹出面板这几种弹层类型的弹出方式不同,需要设置显示时为向上滑动和逐步等动画效果。
最后介绍一下如何实现内容区域滚动时,导航栏自动切换的交互效果。首先需要在导航栏的动态面板中创建对应的状态,然后选中内容框架动态面板,在它的滚动时事件中按照上面的格式加入对应的条件判断即可。
在这个设置用到了条件判断和函数,条件的详细设置见上方的截图。它的原理是当内容框架垂直滚动高度大于70时设置导航栏动态面板的显示状态为2,当内容框架垂直滚动高度大小于70设置导航栏动态面板的显示状态为1。其中用到的This.scrollY函数是获取当前元件的直滚动高度,70的值可以根据需要自己设置。
好了,到此这篇基于设备模板的移动端原型设计方法的分享基本介绍完了。最后提供的是iPhoneX And iPhone8 Mockup 原型模板的源文件下载,大家可以结合本文中的相关介绍进行使用。
最后再给大家分享一套本人整理设计的移动端元件库,这套元件库中的相关元件是可以在这个模板中复用的,后续也会不断的进行优化和完善,有需要的朋友可以关注一下。
在学习和工作中,我们经常需要使用日志来记录程序的运行状态和调试信息。而为了更好地区分不同的日志等级,我们可以使用不同的颜色来呈现,使其更加醒目和易于阅读。
在下图运行结果中,我们使用了 colorlog 库来实现彩色日志输出。通过定义不同日志等级对应的颜色,我们可以在控制台中以彩色的方式显示日志信息。例如,DEBUG 级别的日志使用白色,INFO 级别的日志使用绿色,WARNING 级别的日志使用黄色,ERROR 级别的日志使用红色,CRITICAL 级别的日志使用蓝色。
但是在查看日志文件时,我们会发现日志信息是系统默认的字体颜色,并且前后多了一些特殊符号,例如 [32m 等。这是因为在控制台中使用的是 ANSI 转义序列来实现彩色文本效果,而这些特殊符号是 ANSI 转义序列的一部分。如下图所示:
现在有一个需求,在前端页面直接查看日志内容并还原彩色文本效果,因此,我们将进行以下内容讲解:
本文代码点击此处跳转,往期系列文章请访问博主的 项目实战专栏,博文中的所有代码全部收集在博主的 GitHub 仓库中;
ANSI 转义序列是美国国家标准化组织(American National Standards Institute,ANSI)制定的标准,是一种用于控制文本终端显示的特殊字符序列。它们以 3[ 开头,以字母和数字组合的形式表示不同的控制功能。
ANSI 转义序列可以用于控制文本的颜色、背景色、文本样式(如粗体、斜体等)、光标位置、清屏等操作。通过在输出文本中插入适当的 ANSI 转义序列,可以实现丰富的终端显示效果。
以下是一些常用的 ANSI 转义序列示例:
需要注意的是,ANSI 转义序列在不同的终端和操作系统上的支持程度可能会有所不同。在某些终端中,可能无法正确解释和显示 ANSI 转义序列。
我们以 3[31m 和 3[42m 为例,输出一个绿底红字的句子 Hello World! --sidiot.,代码如下所示:
log.debug("3[42m3[31mHello World! --sidiot.3[0m3[0m")
运行结果:
这里的话,我们使用 Python 的 http.server 模块来启动一个简单的 HTTP 服务器。
比较快捷的方式就是在日志文件夹中打开终端,输入 python -m http.server 8888 即可,运行结果如下所示:
不过这种方式相对来说还是不太安全的,因此我们可以通过设置白名单的方式,来规避一些潜在的安全隐患,代码如下所示:
import http.server
import socketserver
class HTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def check_client_address(self):
# 设置白名单,只允许特定的IP地址或主机访问
whitelist = ['127.0.0.1', 'localhost']
client_address = self.client_address[0]
if client_address not in whitelist:
self.send_response(403)
self.end_headers()
self.wfile.write(b'Forbidden. Please contact sidiot.')
return False
return True
def do_GET(self):
if not self.check_client_address():
return
super().do_GET()
with socketserver.TCPServer(('0.0.0.0', 8888), HTTPRequestHandler) as httpd:
httpd.serve_forever()
目前本机的 IP 为 192.168.124.23,当我们以 127.0.0.1 来访问 8888 服务端口时,访问是成功的,但是当我们用 192.168.124.23 来访问服务端口时,访问是失败的。
运行结果:
现在我们点击文件,它会直接通过浏览器直接下载,但是我们需要的是在网页上能够直接阅览文件中的内容,因此我们可以从 do_GET() 下手。
我们可以设计一个根据传入的文件名参数,读取本地文件并作为响应结果进行返回的方法,然后根据一定的规则进行触发,代码如下所示:
def read_file(self):
try:
self.send_response(200)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.end_headers()
self.wfile.write(open(self.path[6:], 'rb').read())
except FileNotFoundError:
self.send_response(404)
self.end_headers()
self.wfile.write(b'File not found!')
def do_GET(self):
if self.check_client_address():
if self.path.startswith("/?log="):
self.read_file()
else:
super().do_GET()
上述代码通过检查请求的资源路径来处理 GET 请求。如果请求的资源路径前缀是 /?log=,且是当前目录下存在的日志文件,它会读取文件并将其内容作为响应发送。否则,它会使用基类的默认行为处理普通的 GET 请求。
运行结果:
至此,我们已经实现了前端页面直接查看日志内容的功能。
原理分析
当我们想要在前端页面展示 ANSI 字体的彩色效果时,我们只需要简单地将 ANSI 转义序列转换成相应的 HTML 代码就可以实现了。这个转换过程实际上可以通过编写一个 Python 函数来实现,该函数可以接受包含 ANSI 控制码的字符串作为输入,并将其转换为带有相应样式的 HTML 代码输出,代码如下所示:
def convert_ansi_to_html(ansi_text):
ansi_to_html = {
'\x1b[31m': '<span style="color: red;">',
'\x1b[42m': '<span style="background-color: green;">',
...,
}
html_text = re.sub(r'\x1b[[0-9;]*m', lambda match: ansi_to_html.get(match.group(0), ''), ansi_text)
return html_text
if __name__ == '__main__':
ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
print(ansi)
html = convert_ansi_to_html(ansi)
print(f"convert content: {html}")
需要注意的是,在 ANSI 转义序列中,\x1b 和 3 都代 表ASCII 码中的 Escape 字符,用于开始一个转义序列。
运行结果:
使用 ansiconv 转换
接下来,我们借助已有的库函数 ansiconv 进行 ANSI 的转换。
通过 pip 进行安装:
pip install ansiconv
根据 ansiconv 的官方文档使用其中的三个方法 to_plain(),to_html() 和 base_css() 来实现在前端页面展示 ANSI 字体的彩色效果,代码如下所示:
import ansiconv
ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
print(f"Ansi: {ansi}")
plain = ansiconv.to_plain(ansi)
html = ansiconv.to_html(ansi)
print(f"Convert Plain: {plain}")
print(f"Convert HTML: {html}")
在 base_css() 中会有相关的 CSS 映射表,如下所示:
css_rule('.ansi31', color="#FF0000"),
css_rule('.ansi42', background_color="#00FF00"),
运行结果:
研究 ansiconv 源码
我们将通过研究 ansiconv 的源码,以便深入了解它是如何将 ANSI 转换成纯文本或 HTML 代码的工作原理。
to_plain() 的源码如下所示:
上述代码使用正则表达式匹配字符串中的 ANSI 转义序列,并将其替换为空字符串,从而得到不包含转义序列的纯文本。
正则表达式的含义如下:
我们通过 re.findall() 方法来获取所有匹配的结果,这样够清晰地捕获所有符合条件的匹配项,从而更好地理解 ansiconv 是如何进行 ANSI 到纯文本的转换,代码如下所示:
ansi = "\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m"
print(re.findall(r'\x1B[[0-9;]*[ABCDEFGHJKSTfmnsulh]', ansi))
运行结果:
to_html() 的源码如下所示:
上述代码将 ANSI 字符串分割成块,并对每个块调用 _block_to_html() 函数进行解析和转换,同时还处理了 ANSI 命令 "A",模拟向上移动光标的行为。如果 replace_newline 为 True,则 HTML 字符串中的换行符 \n 将替换为 <br />\n 以保留 HTML 输出中的换行符。
其中 _block_to_html() 的源码如下所示:
上述代码使用正则表达式匹配 ANSI 代码,并根据匹配结果生成对应的 HTML 代码。
正则表达式的含义:
我们可以通过运行源码里的部分代码来帮助理解,代码如下所示:
text = ("\x1B[0;32;45msidiot\n"
"\033[42m\033[31mHello World! --sidiot.\033[0m\033[0m")
print(text)
blocks = text.split('\x1B')
print(blocks)
for block in blocks:
match = re.match(r'^[(?P<code>\d+(?:;\d+)*)?(?P<command>[Am])', block)
if match is not None:
print("\nmatch:", match, ", code:", match.group('code'), ", command:", match.group('command'))
运行结果:
实际应用
通过深入理解 ANSI 转换思路和 ansiconv 源码,我们可以为之前的 http.server 服务带来全新的优化。
首先,将原先的 read_file() 方法进行优化,代码如下所示:
def read_file(self, content_type, file_io):
try:
self.send_response(200)
self.send_header("Content-Type", f"{content_type}; charset=utf-8")
self.end_headers()
self.wfile.write(file_io)
except FileNotFoundError:
self.send_response(404)
self.send_header("Content-Type", "text/plain; charset=utf-8")
self.end_headers()
self.wfile.write(b'File not found!')
上述代码通过接收 content_type 和 file_io 两个参数,实现将自定义内容作为响应返回给客户端。
然后修改请求路径,使其能够返回纯文本和 HTML 两种不同类型的内容,代码如下所示:
def do_GET(self):
if self.check_client_address():
if self.path.startswith("/?plain="):
file = open(self.path[8:], 'rb').read()
plain = ansiconv.to_plain(file.decode('UTF-8'))
self.read_file("text/plain", plain.encode())
elif self.path.startswith("/?html="):
file = open(self.path[7:], 'rb').read()
conv = ansiconv.to_html(file.decode('UTF-8'))
css = ansiconv.base_css()
html = """
<html>
<head><style>{0}</style></head>
<body>
<pre class="ansi_fore ansi_back">{1}</pre>
</body>
</html>
""".format(css, conv)
print(html)
self.read_file("text/html", html.encode())
else:
super().do_GET()
这里要注意的是,需要设置 CSS 样式,不然 class 类是无法进行渲染的。
纯文本运行结果:
HTML 运行结果:
在本文中,我们探讨了如何实现将 ANSI 字体在前端页面进行彩色展示的方法。在前端页面中直接显示 ANSI 转义序列是不起作用的,因为浏览器不会解析和处理这些转义序列。
为了在前端页面实现彩色展示,我们介绍了一种方法,即将 ANSI 转义序列转换为对应的 HTML 代码。通过解析 ANSI 转义序列并将其转换为适当的 HTML 标签和样式,我们可以在前端页面上还原彩色文本的效果。
在本文中,我们使用了 Python 中的 ansiconv 库来实现 ANSI 转换。该库提供了 to_plain 和 to_html 两个方法,分别用于将 ANSI 转义序列转换为纯文本和 HTML 代码。我们还展示了如何使用这些方法来转换 ANSI 字符串,并在前端页面上显示转换后的结果。
通过本文的介绍,读者可以了解到如何在前端页面实现彩色文本的展示,从而提升用户体验和可读性。无论是在日志查看器、终端模拟器还是其他需要展示彩色文本的应用中,这种技术都能发挥重要作用。
以上就是 从终端到浏览器:实现 ANSI 字体在前端页面的彩色展示 的所有内容了,希望本篇博文对大家有所帮助!欢迎大家持续关注我的博客,一起分享学习和成长的乐趣!✨
作者:sidiot
链接:https://juejin.cn/post/7381820436274184202
*请认真填写需求信息,我们会在24小时内与您取得联系。