自动化测试-Selenium
一. Selenium介绍
selenium 是用来做web自动化测试的框架,支持各种浏览器,各种,支持各种语言
原理:
二. 元素定位
2.1 XPath 定位
绝对路径: /html/head/title
相对路径以双斜杠开头,常见的相对路径定位有以下几种:
<1>相对路径+索引: 索引是从1开始的
<2>相对路径+属性值:
<3>相对路径+通配符
<4>相对路径+文本匹配
2.2 CSS定位
• id选择器: #id
• 类选择器: .class
• 标签选择: 标签名
• 后代选择器: 父级选择器 子级选择器
三. 操作测试对象
3.1 常见API
• click 点击对象
• send_keys 在对象上模拟按键输入
• clear 清除对象输入的文本内容
• submit 提交
• getAttribute 获取标签中value属性所对应的值
• text 由于获取元素的文本信息
public class Demo1 {public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver =new ChromeDriver(options);//获取网址webDriver.get("https://www.sogou.com");//获取value标签元素文本信息String str=webDriver.findElement(By.xpath("//input[@value=\"搜狗搜索\"]")).getAttribute("value");System.out.println(str);//输入搜索内容webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.xpath("//input[@value=\"搜狗搜索\"]")).click();Thread.sleep(3000);//找到并打印所有a标签下em标签中的内容List<WebElement> elements=webDriver.findElements(By.cssSelector("a em"));for (int i = 0; i < elements.size(); i++) {System.out.println(elements.get(i).getText());}Thread.sleep(3000);webDriver.close();}
}
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);//由于此处的搜狗搜索在form标签中,因此能够顺利提交//webDriver.findElement(By.cssSelector("#stb")).click();webDriver.findElement(By.cssSelector("#stb")).submit();Thread.sleep(3000);//此时代码是会报错的,因为a标签并不在form标签内//webDriver.findElement(By.cssSelector("#weixinch")).submit();webDriver.close();}
3.2 等待
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.baidu.com/");webDriver.findElement(By.cssSelector("#s-top-loginbtn")).click();//隐式等待//webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);//显示等待,若加载出直接执行下面代码,若在指定时间内没有加载出来,就抛异常new WebDriverWait(webDriver,10).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#s-top-loginbtn")));//强制等待3sThread.sleep(3000);webDriver.findElement(By.xpath("//*[@id=\"TANGRAM__PSP_11__userName\"]")).sendKeys("1111");webDriver.close();}
隐式等待等待的是整个页面的元素,而显示等待等待的是一定的条件.
3.3 打印信息(标题/URL)
public static void main(String[] args) {ChromeOptions options =new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");String title=webDriver.getTitle();String url=webDriver.getCurrentUrl();System.out.println("当前标题:"+title+"当前url:"+url);webDriver.close();}
3.4 浏览器的操作
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#stb")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);//后退一步webDriver.navigate().back();Thread.sleep(3000);//前进一步webDriver.navigate().forward();Thread.sleep(3000);//使屏幕最大化webDriver.manage().window().maximize();Thread.sleep(3000);//全屏webDriver.manage().window().fullscreen();Thread.sleep(3000);//自定义窗口大小webDriver.manage().window().setSize(new Dimension(600,1000));Thread.sleep(3000);//滑动滚动条((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=19999");}
3.5 键盘事件
通过sendKeys()调用按键:
• sendkeys(Keys.TAB) #TAB
• sendKeys(Keys.ENTER) #回车
• sendKeys(Keys.SPACE) #空格键
• sendKeys(Keys.ESCAPE) #回退键(Esc)
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.SPACE);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys("软件开发");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);}
键盘组合键用法
sendKeys(Keys.CONTROL,"a") #全选 (Ctrl+a)
sendKeys(Keys.CONTROL,"c") #复制 (Ctrl+c)
sendKeys(Keys.CONTROL,"x") #剪切 (Ctrl+x)
sendKeys(Keys.CONTROL,"v") #粘贴 (Ctrl+v)
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"a");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"x");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.CONTROL,"v");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);}
3.6 鼠标事件
Actions类:
• contextClick() 右击
• doubleClick() 双击
• dragAndDrop() 拖动
• moveToElement() 移动
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.sogou.com/");webDriver.findElement(By.cssSelector("#query")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#query")).sendKeys(Keys.ENTER);Actions actions=new Actions(webDriver);Thread.sleep(3000);//需要现将鼠标移动到要操作的元素,然后右击,要perform()才会有效果actions.moveToElement( webDriver.findElement(By.cssSelector("#sogou_weixin"))).contextClick().perform();}
四. 特殊操作
为了方便测试的演示,测试的页面都是自制的。
4.1 定位一组元素
页面:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio1</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio2</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>
测试:
public static void main(String[] args) {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test1.html?_ijt=a28mk13t2kbijoe7d2clon53lj&_ij_reload=RELOAD_ON_SAVE");webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.DAYS);List<WebElement> webElements=webDriver.findElements(By.xpath("//input[@type=\"checkbox\"]"));for (int i = 0; i < webElements.size(); i++) {System.out.println(webElements.get(i).getAttribute("type"));}}
4.2 多层框架/窗口定位
多框架定位
如果有内嵌网页框架,需要先转到框架才能操作框架内元素。
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();//允许所有请求options.addArguments("--remote-allow-origins=*");WebDriver webDriver =new ChromeDriver(options);webDriver.get("https://mail.163.com/");//需要先定位到框架,再对框架内元素进行操作webDriver.switchTo().frame(webDriver.findElement(By.xpath("//iframe")));Thread.sleep(3000);webDriver.findElement(By.xpath("//input[@name=\"email\"]")).sendKeys("12345");}
窗口的切换
在浏览器中每个窗口都有一个句柄来标识
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("Https://www.baidu.com");//获取当前句柄String handle= webDriver.getWindowHandle();System.out.println(handle);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();Set<String> hanles=webDriver.getWindowHandles();for (String h:hanles) {handle=h;}webDriver.switchTo().window(handle);Thread.sleep(3000);webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");Thread.sleep(3000);webDriver.findElement(By.cssSelector("#s_btn_wr")).click();}
4.3 下拉框操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>下拉框</title>
</head>
<body>
<select id="ShippingMethod"onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod"><option value="12.51">UPS Next Day Air ==> $12.51</option><option value="11.61">UPS Next Day Air Saver ==> $11.61</option><option value="10.69">UPS 3 Day Select ==> $10.69</option><option value="9.03">UPS 2nd Day Air ==> $9.03</option><option value="8.34">UPS Ground ==> $8.34</option><option value="9.25">USPS Priority Mail Insured ==> $9.25</option><option value="7.45">USPS Priority Mail ==> $7.45</option><option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test3.html?_ijt=dcl94qtill9arl6odicib469be&_ij_reload=RELOAD_ON_SAVE");WebElement webElement=webDriver.findElement(By.cssSelector("#ShippingMethod"));Select select=new Select(webElement);Thread.sleep(3000);//通过标签 value选择 select.selectByValue("9.03");Thread.sleep(3000);//通过下标选择,下标从零开始select.selectByIndex(2);}
4.4 弹窗操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<button onclick="Click()">这是一个弹窗</button>
</body>
<script type="text/javascript">function Click() {let name = prompt("请输入姓名:");let parent = document.querySelector("body");let child = document.createElement("div");child.innerHTML = name;parent.appendChild(child)}
</script>
</html>
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test4.html?_ijt=e7mju27ab5d214o41bhvcqjf4r&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.xpath("//*[text()=\"这是一个弹窗\"]")).click();Thread.sleep(3000);//alert弹窗取消webDriver.switchTo().alert().dismiss();Thread.sleep(3000);webDriver.findElement(By.xpath("//*[text()=\"这是一个弹窗\"]")).click();Thread.sleep(3000);webDriver.switchTo().alert().sendKeys("软件测试");Thread.sleep(3000);webDriver.switchTo().alert().accept();}
4.5 文件操作
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="file">
</body>
</html>
public static void main(String[] args) {ChromeOptions options =new ChromeOptions();options.addArguments("--remote-allow-origins");WebDriver webDriver=new ChromeDriver(options);webDriver.get("http://localhost:63342/SeleniumTest/page/test5.html?_ijt=klnnrj3i4pn2rhg6cl7a63qibe&_ij_reload=RELOAD_ON_SAVE");webDriver.findElement(By.cssSelector("input")).sendKeys("E:\\test");}
4.6 quit和close
quit 关闭了整个浏览器,同时会清空浏览器的cookie,close关闭的是get时获取的页面.
public static void main(String[] args) throws InterruptedException {ChromeOptions options=new ChromeOptions();options.addArguments("--remote-allow-origins=*");WebDriver webDriver=new ChromeDriver(options);webDriver.get("https://www.baidu.com");webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();Thread.sleep(3000);//webDriver.close();webDriver.quit();}
4.7 截图
public static void main(String[] args) throws InterruptedException, IOException {WebDriver webDriver=new ChromeDriver();webDriver.get("Https://www.baidu.com");webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");webDriver.findElement(By.cssSelector("#su")).click();Thread.sleep(3000);File file=((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File("E:\\Code\\SeleniumTest\\picture.png"));}
注:截图操作需要另外引入一个common-io的依赖
Maven Repository: commons-io » commons-io » 2.11.0 (mvnrepository.com)
相关文章:

自动化测试-Selenium
一. Selenium介绍 selenium 是用来做web自动化测试的框架,支持各种浏览器,各种,支持各种语言 原理: 二. 元素定位 2.1 XPath 定位 绝对路径: /html/head/title 相对路径以双斜杠开头,常见的相对路径定位有以下几种: <1>相对路径索引: 索引是从1开始的 <2>相…...
基于单片机的温湿度检测系统设计
目录 摘 要... 2 第一章 绪论... 5 1.1 研究课题背景... 5 1.2 国内外发展概况... 7 1.3 课题研究的目的... 8 1.4 课题的研究内容及章节安排... 8 第二章 温湿度检测系统控制系统的设计方案... 10 2.1 设计任务及要求... 10 2.2 温湿度检测系统总体设计方…...
C# 关于异常处理 try-catch语句的使用
在实际应用中,比如涉及文件读写、网络通信时,会因为文件不存在、权限不够、网络异常等原因引发异常,或者对数据库连接、查询、更新等操作,会因为连接超时、语法错误、唯一约束冲突等引发异常。 看过去的代码,当进行上…...
【LeeCode】26.删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums ,请你原地删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k ,你需…...
4-Docker命令之docker create
1.docker create介绍 docker create命令是用于创建一个新的容器,等价于docker run -d命令,但是与docker run -d不同的是,docker create创建的容器并未实际启动,需要指定docker start命令启动。 2.docker create用法 docker create [参数] [root@centos79 ~]# docker cr…...
leetcode每日一题33
86.分隔链表 因为对链表中的一个节点进行更换位置的操作需要知道该节点的上一个节点 所以建立一个虚拟头节点 ListNode* pnew ListNode(-201,head);根据题意,我们需要找到第一个大于x或等于x的节点large 并且将第一个大于或等于x的节点large后的所有小于x的节点都…...

性能测试【一】:Jmeter的常用操作
性能测试【一】:Jmeter的常用操作 一、使用命令行方式运行Jmeter1、为什么2、怎么用3、示例4、结果文件 二、生成动态报告1、准备2、命令3、报告示例4、报告释义 三、使用问题汇总 推荐使用命令行运行,GUI方式会经常卡死,尤其跑稳定性 一、使…...

【JAVA】SpringBoot + mongodb 分页、排序、动态多条件查询及事务处理
【JAVA】SpringBoot mongodb 分页、排序、动态多条件查询及事务处理 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mongodb ↓ -->&…...

nrm安装及使用
一、介绍 nrm 是一个 Node.js 的 registry 管理工具,它允许你快速地在不同的 npm registry 之间进行切换。通过使用 nrm,你可以方便地将 npm 的 registry 切换为淘宝镜像、npm 官方镜像或者其他定制的镜像,以加快包的下载速度。nrm仓库请点击…...

docker报错standard init linux.go:228 exec user process caused: exec format error
1、报错 使用Dockerfile自己做的服务镜像,docker run时启动失败,报错如下: standard init linux.go:228 exec user process caused: exec format error2、原因一 当前服务器的CPU架构和构建镜像时的CPU架构不兼容。比如做镜像是在arm机器下…...
Docker 的基本概念和优势,以及在应用程序开发中的实际应用。
Docker 是一种容器化技术,它将一个应用程序及其所有依赖项打包在一起,形成一个独立的、可移植的容器。这个容器可以在任何支持 Docker 的操作系统上运行,而且具有很好的可移植性和可扩展性。以下是 Docker 的基本概念和优势: 镜像…...

libmosquitto库的一个bug,任务消息id(mid)分配后不起作用
代码如图所示: 当订阅了所有主题后,每个主题的mid是他们的下标索引加100的数字,可是实际打印出来的值是: mid依然是1,2,这个参数在这里失效了,不知道是bug还是mqtt的什么机制?...

亚马逊云科技re:Invent大会:云计算与生成式AI共筑科技新局面,携手构建未来
随着科技的飞速发展,云计算和生成式 AI 已经成为了推动科技进步的重要力量。这两者相互结合,正在为我们创造一个全新的科技局面。 亚马逊云科技的re:Invent大会再次证明了云计算和生成式AI的强大结合正在塑造科技的新未来。这次大会聚焦了云计算的前沿技…...

Docker 部署 Nacos(单机),利用 MySQL 数据库存储配置信息
前面的话 默认你已经懂 Docker、docker-compose Nacos版本:v2.2.3 MySQL 版本:8.2.0 一、下载 打开 Nacos 官网 官网地址:官网 点击手册 左侧 Nacos Docker 克隆项目到本地 # 克隆项目,如果提示连接不到 github 请自行解决 …...
【LeeCode】35.搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。 解: class Solution {public int searchInsert(int[] nums, int target) {int …...

18.天气小案例
1►新增带Layout组件的页面 直接在views文件夹下面新增weather.vue。然后随便写一个123,现在先让我们页面能跳过去先。 让页面能跳过去,有好几种方法: 1、在菜单管理自己添加一个菜单,然后把菜单分配给某个角色,再把…...

医保线上购药系统:代码驱动的医疗创新
医保线上购药系统,这是一个融合技术和医疗的创新典范。本文将通过简单的技术代码示例,为您揭示这一系统是如何通过技术驱动医疗创新,为用户提供更智能、便捷的健康管理体验的。 1. 前端界面开发 使用React框架,我们可以轻松构建…...

VMware OpenSLP漏洞解决方案
PS:早期为客户做VMware检测的方法,大家如有遇到可参考 OpenSLP堆溢出漏洞攻击大量ESXI服务器,该漏洞编号为CVE-2021-21974,由 OpenSLP 服务中的堆溢出问题引起 大于以下版本则不受影响 ESXi versions 7.x prior to ESXi7…...

UEditor编辑器实现上传图片自动加水印功能PHP源码
UEditor编辑器是百度旗下的免费开源富文本编辑器,使用很方便,但是也有缺点,比如,上传图片不能自动添加水印,下边我们就来说说如何在UEditor编辑器中自动实现上传图片添加水印功能,操作很简单。 首先找到UEditor/PHP目录下的Uploader.class.php的文件,打开该文件,找到以…...

【从浅识到熟知Linux】基本指定之find、grep、head和tail
🎈归属专栏:从浅学到熟知Linux 🚗个人主页:Jammingpro 🐟每日一句:一篇又一篇,学写越上头。 文章前言:本文介绍find、grep、head和tail指令用法并给出示例和截图。 文章目录 find基本…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...