JavaScript学习目录
- 一、JavaScript
- 1. 引入方式
- 1.1 内部脚本 (Inline Script)
- 1.2 外部脚本 (External Script)
- 2. 基础语法
- 2.1 声明变量
- 2.2 声明常量
- 2.3 输出信息
- 3. 数据类型
- 3.1 基本数据类型
- 3.2 模板字符串
- 4. 函数
- 4.1 具名函数 (Named Function)
- 4.2 匿名函数 (Anonymous Function)
- 4.2.1 函数表达式
- 4.2.2 箭头函数 (Arrow Function)
- 5. 自定义对象
- 5.1 自定义对象
- 5.2 调用对象属性/方法
- 5.3 JSON - JS对象标记法
- 6. DOM
- 6.1 获取DOM对象
- 6.2 修改DOM对象的内容
- 6.3 其他常用的DOM操作方法
- 7. 事件监听
- 7.1 `addEventListener` 方法
- 7.2 传统`onclick`属性
- 7.3 事件处理的区别与选择
- 8. 常见事件
- 8.1 `type="module"`关键字
- 8.2 `export`关键字
- 8.3 `import`关键字
- 8.4 常见事件
- 8.4.1 鼠标事件
- 8.4.2 键盘事件
- 8.4.3 表单事件
- 8.4.4 焦点事件
- 8.4.5 其他事件
- 二、Vue
- 1. Vue快速入门
- 1.1 数据绑定
- 1.2 模块化脚本加载
- 1.3 响应式数据
- 1.4 应用实例创建与挂载
- 2. Vue生命周期
- 2.1 Vue生命周期的主要阶段
- 2.1.1 创建阶段 (Creation)
- 2.1.2 挂载阶段 (Mounting)
- 2.1.3 更新阶段 (Updating)
- 2.1.4 销毁阶段 (Destroying)
- 2.2 生命周期图示
- 2.3 使用场景
- 三、Axios
- 1. Axios快速入门
- 1.1 Axios GET请求
- 1.2 Axios POST请求
- 1.3 回调函数
- 2. Axios请求方式别名
- 四、案例---员工列表
- 1. Vue 关键知识点总结
- 1.1 `searchForm` 对象
- 1.2 `v-model` 指令
- 1.3 `v-on` 指令
- 1.4 `v-if` 和 `v-else-if` 指令
- 1.5 `v-show` 指令
- 1.6 `v-show` 与 `v-if` 的区别
- 1.7 `v-for` 指令
- 1.8 `async` 和 `await`
- 1.9 URL 解释
- 1.9.1 基础URL
- 1.9.2 查询参数
本文参考黑马程序员:全网首发AI+JavaWeb开发入门
一、JavaScript
1. 引入方式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-引入方式</title>
</head>
<body><!-- <script>//1. 内部脚本alert('Hello JS');</script> --><!-- 2. 外部脚本 --><script src="js/demo.js"></script>
</body>
</html>
js/demo.js
alert('Hello JavaScript');
1.1 内部脚本 (Inline Script)
- 内部脚本是直接嵌入到HTML文档中的JavaScript代码。
- 它们通常放在
<script>
标签内,可以放置在HTML文档的任何位置,但大多数情况下会放在<head>
或<body>
标签内。 - 在给定的代码示例中,内部脚本被注释掉了,因此不会被执行。如果取消注释,
alert('Hello JS');
这行代码将会创建一个弹窗,显示消息"Hello JS"。
1.2 外部脚本 (External Script)
- 外部脚本是将JavaScript代码保存在一个单独的
.js
文件中,并通过<script>
标签的src
属性来引用这个文件。 - 这种方法有助于保持HTML和JavaScript代码的分离,使得代码更易于维护和重用。
- 在示例中,
<script src="js/demo.js"></script>
这行代码用来加载位于相对路径js/demo.js
的外部JavaScript文件。这意味着HTML文档所在的目录下应该有一个名为js
的子目录,其中包含了一个名为demo.js
的文件。 - 使用外部脚本还可以让浏览器缓存JavaScript文件,从而加快页面加载速度,特别是在用户访问同一网站的多个页面时。
2. 基础语法
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-基础语法</title>
</head>
<body><script>//1. 声明变量// let a = 10;// a = "Hello";// a = true;// alert(a); //弹出框//2. 声明常量const PI = 3.14;//PI = 5.0;console.log(PI); //输出到控制台// document.write(PI); //输出到body区域(不常用)</script>
</body>
</html>
2.1 声明变量
- 在JavaScript中,可以使用
let
关键字来声明变量。let
允许你声明一个块级作用域的局部变量。 - 变量可以在声明后被重新赋值。在给定的代码示例中,变量
a
被注释掉了,但是按照其设计,它最初被赋予了一个数值10
,然后又被赋予了字符串"Hello"
,最后是布尔值true
。这展示了JavaScript是一种动态类型语言,变量可以在不同的时间点持有不同类型的值。
2.2 声明常量
- 使用
const
关键字可以声明一个常量,意味着这个变量一旦被赋值,就不能再改变它的值。这并不意味着const
定义的对象或数组的内容不可变,只是不能重新赋值给该常量引用。 - 在代码示例中,常量
PI
被赋予了值3.14
。如果尝试再次为PI
赋值(如PI = 5.0;
),将会导致错误,因为这是不允许的操作。
2.3 输出信息
alert()
函数用于创建一个弹窗,向用户显示一条消息。此功能在示例中被注释掉了。console.log()
方法用于将信息输出到浏览器的开发者工具中的控制台,这对于调试非常有用。document.write()
方法可以用来直接向文档写入文本字符串。这种方法在现代开发中不常用,因为它会覆盖页面上的现有内容,并且只能在页面加载期间使用。
3. 数据类型
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-数据类型</title>
</head>
<body><script>//1. 数据类型// alert(typeof 10); //number// alert(typeof 1.5); //number// alert(typeof true); //boolean// alert(typeof false); //boolean// alert(typeof "Hello"); //string// alert(typeof 'JS'); //string// alert(typeof `JavaScript`); //string// alert(typeof null); //null ? -> object// let a ;// alert(typeof a); //undefined//2. 模板字符串 - 简化字符串拼接let name = 'Tom';let age = 18;console.log('我是'+name+', 我今年'+age+'岁');console.log(`我是${name}, 我今年${age}岁`);</script>
</body>
</html>
3.1 基本数据类型
-
JavaScript中有几种基本的数据类型,包括
number
、boolean
、string
、null
、undefined
等。-
number
: 用于表示数值,包括整数(如10
)和浮点数(如1.5
)。在JavaScript中,所有的数字都是以64位浮点数格式存储的。 -
boolean
: 表示逻辑值,只有两个值:true
和false
。 -
string
: 用于表示文本,可以使用单引号(’…’)、双引号("…")或反引号(...
)来定义字符串。 -
null
: 表示一个空值或不存在的对象,在技术上它是一个对象类型的特殊值,虽然这在语义上可能有些混淆。 -
undefined
: 当声明了一个变量但没有赋值时,默认的值就是undefined
。它也用来表示某个变量或属性不存在。
-
3.2 模板字符串
- 模板字符串是增强版的字符串,允许嵌入表达式。它们使用反引号(
`
)来包裹,并且可以在其中直接插入变量和表达式,通过${expression}
语法。 - 使用模板字符串可以简化字符串拼接,使得代码更易读和编写。例如,
console.log(我是${name}, 我今年${age}岁); 这行代码会输出 "我是Tom, 我今年18岁;"
,其中${name}
和${age}
会被相应的变量值替换。
typeof
运算符:typeof
是一个运算符,返回一个字符串,表示操作数的数据类型。上面的注释部分展示了如何使用typeof
来检查不同类型的值。
注意事项:
- 注意到
typeof null
返回的是"object"
,这是一个历史遗留问题,是因为JavaScript最初实现上的一个错误,但它一直保留至今以保持向后兼容性。
4. 函数
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-函数</title>
</head>
<body><script>//1. 函数定义及调用 - 具名函数// function add(a,b){// return a + b;// }// let result = add(10,20);// console.log(result);//2. 函数定义及调用 - 匿名函数//2.1 函数表达式// let add = function(a,b){// return a + b;// }// let result = add(100,200);// console.log(result);//2.2 箭头函数let add = (a,b) => {return a + b;}let result = add(1000,2000);console.log(result);</script>
</body>
</html>
4.1 具名函数 (Named Function)
- 具名函数是使用
function
关键字定义,并且具有一个明确的名字。这个名称可以在函数内部用于递归调用,也可以在调试或堆栈跟踪时提供有用的上下文信息。 - 在示例中,
add
函数接收两个参数a
和b
,并返回它们的和。虽然这部分被注释掉了,但其目的是展示如何定义和调用一个具名函数。
4.2 匿名函数 (Anonymous Function)
- 匿名函数是没有名字的函数。它们通常作为函数表达式来使用,可以赋值给变量、作为参数传递给其他函数,或者立即执行(IIFE)。
4.2.1 函数表达式
- 函数表达式是将匿名函数赋值给一个变量的方式。这使得函数可以通过该变量名进行调用。
- 示例中的
add
变量指向了一个匿名函数,该匿名函数接收两个参数并返回它们的和。通过add(100,200)
调用它,结果为300。
4.2.2 箭头函数 (Arrow Function)
- 箭头函数是ES6引入的一种更简洁的函数书写方式。它们有较短的语法并且不会绑定自己的
this
,arguments
,super
,或new.target
。 - 在代码示例中,
add
是一个箭头函数,它同样接收两个参数并返回它们的和。这里使用了大括号{}
来包裹函数体,因为函数体内有多行代码或需要显式地返回一个值。 - 如果箭头函数只有一行代码,可以直接省略大括号和
return
关键字。例如:let add = (a, b) => a + b;
5. 自定义对象
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-函数</title>
</head>
<body><script>//1. 自定义对象// let user = {// name: 'Tom',// age: 18,// gender: '男',// sing: function(){// alert(this.name + '悠悠的唱着最炫的民族风~')// }// }//let user = {// name: 'Tom',// age: 18,// gender: '男',// sing(){// alert(this.name + '悠悠的唱着最炫的民族风~')// }//}// let user = {// name: 'Tom',// age: 18,// gender: '男',// sing: () => { //注意: 在箭头函数中, this并不指向当前对象 - 指向的是当前对象的父级 【不推荐】// alert(this + ':悠悠的唱着最炫的民族风~')// }// }//2. 调用对象属性/方法//alert(user.name);//user.sing();//3. JSON - JS对象标记法let person = {name: 'itcast',age: 18,gender: '男'}alert(JSON.stringify(person)); //js对象 --> json字符串let personJson = '{"name": "heima", "age": 18}';alert(JSON.parse(personJson).name);</script>
</body>
</html>
5.1 自定义对象
- 在JavaScript中,可以使用对象字面量的方式创建对象。对象是一组无序的键值对集合,其中键是字符串(或符号),值可以是任何有效的JavaScript数据类型,包括函数。
- 对象的方法可以通过两种方式定义:传统函数表达式和简化的ES6语法(去掉
function
关键字)。但是要注意,在箭头函数中,this
关键字的行为与常规函数不同,它不会绑定到当前对象,而是继承自外层作用域,因此在对象方法中通常不推荐使用箭头函数来定义方法。
5.2 调用对象属性/方法
- 可以通过点
.
操作符访问对象的属性或调用其方法。例如,user.name
会返回用户的名字,而user.sing()
将执行sing
方法,并弹出一个带有消息的对话框。
5.3 JSON - JS对象标记法
-
JSON是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成。它基于JavaScript编程语言的一个子集。
-
JSON.stringify()
方法用于将JavaScript对象转换为JSON字符串。这在需要发送数据给服务器或存储时非常有用。alert(JSON.stringify(person)); // 将 person 对象转换为 JSON 字符串并显示
-
JSON.parse()
方法用于解析JSON字符串,构造由字符串描述的JavaScript值或对象。这在接收来自服务器的数据或从存储中读取时非常有用。alert(JSON.parse(personJson).name); // 解析 JSON 字符串并访问 name 属性
6. DOM
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-DOM</title>
</head>
<body><h1 id="title1">11111</h1><h1>22222</h1><h1>33333</h1><script>//1. 修改第一个h1标签中的文本内容//1.1 获取DOM对象// let h1 = document.querySelector('#title1');//let h1 = document.querySelector('h1'); // 获取第一个h1标签let hs = document.querySelectorAll('h1');//1.2 调用DOM对象中属性或方法hs[0].innerHTML = '修改后的文本内容';</script>
</body>
</html>
6.1 获取DOM对象
document.querySelector
方法用于返回文档中与指定的选择器或选择器组匹配的第一个Element节点,如果没有任何匹配,则返回null。- 使用ID选择器:
document.querySelector('#title1')
会选取具有id="title1"
的元素。 - 使用标签名选择器:
document.querySelector('h1')
会选择文档中的第一个<h1>
元素。
- 使用ID选择器:
document.querySelectorAll
方法用于返回一个静态(不是实时更新)的NodeList对象,包含文档中所有与指定的选择器或选择器组匹配的元素。
6.2 修改DOM对象的内容
- 在代码示例中,通过
querySelectorAll('h1')
获取了所有的<h1>
元素,并存储在变量hs
中。然后通过访问hs[0]
来定位到第一个<h1>
元素,并使用innerHTML
属性设置其新的文本内容为“修改后的文本内容”。 innerHTML
属性可以用来读取或设置元素的内容,包括HTML标记。如果只想修改纯文本而不涉及HTML结构,可以使用textContent
属性。
6.3 其他常用的DOM操作方法
getElementById(id)
:通过元素的ID获取单个元素。getElementsByClassName(name)
:通过类名获取一组元素。getElementsByTagName(name)
:通过标签名获取一组元素。appendChild(child)
:向节点添加子节点。removeChild(child)
:从节点中移除子节点。insertBefore(newElement, referenceElement)
:在参考元素之前插入新元素。setAttribute(name, value)
和getAttribute(name)
:分别为设置和获取元素的属性值。
7. 事件监听
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS事件</title>
</head>
<body><input type="button" id="btn1" value="点我一下试试1"><input type="button" id="btn2" value="点我一下试试2"><script>//事件监听 - addEventListener (可以多次绑定同一事件)document.querySelector('#btn1').addEventListener('click', () => {console.log('试试就试试~~');});document.querySelector('#btn1').addEventListener('click', () => {console.log('试试就试试22~~');});//事件绑定-早期写法 - onclick (如果多次绑定同一事件, 覆盖) - 了解document.querySelector('#btn2').onclick = () => {console.log('试试就试试~~');}document.querySelector('#btn2').onclick = () => {console.log('试试就试试22~~');}</script>
</body>
</html>
7.1 addEventListener
方法
addEventListener
是现代推荐的方式来为DOM元素添加事件监听器。它允许你为同一个事件类型(如点击事件)绑定多个不同的处理函数,而不会相互覆盖。- 在示例中,
#btn1
按钮通过addEventListener
方法绑定了两个点击事件处理函数。当点击#btn1
时,这两个函数都会被执行,依次输出“试试就试试~~”和“试试就试试22~~”。
7.2 传统onclick
属性
- 早期的事件绑定方式是直接设置元素的
onclick
属性。这种方式只能为一个元素的特定事件指定一个处理函数;如果再次为同一事件设置onclick
,则会覆盖之前的定义。 - 示例中的
#btn2
按钮使用了onclick
属性来绑定点击事件处理函数。由于第二次赋值覆盖了第一次的赋值,因此只有最后一个绑定的处理函数会被执行,即只会输出“试试就试试22~~”。
7.3 事件处理的区别与选择
- 使用
addEventListener
可以更灵活地管理事件,特别是当你需要在不同地方或时间点添加多个事件处理器时。此外,它还支持事件捕获阶段和冒泡阶段的选择,提供了更多的控制。 - 而
onclick
等内联事件处理程序较为简单直接,但在复杂的应用中可能会导致代码难以维护,并且容易被后续的脚本覆盖。
8. 常见事件
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>JS-事件-常见事件</title>
</head><body><form action="" style="text-align: center;"><input type="text" name="username" id="username"><input type="text" name="age" id="age"><input id="b1" type="submit" value="提交"><input id="b2" type="button" value="单击事件"></form><br><br><br><table width="800px" border="1" cellspacing="0" align="center"><tr><th>学号</th><th>姓名</th><th>分数</th><th>评语</th></tr><tr align="center"><td>001</td><td>张三</td><td>90</td><td>很优秀</td></tr><tr align="center" id="last"><td>002</td><td>李四</td><td>92</td><td>优秀</td></tr></table><!-- type="module" 模块化JS --><script src="./js/eventDemo.js" type="module"></script>
</body></html>
8.1 type="module"
关键字
该部分代码有如下结构
项目根目录
├── 常见事件.html
└── js├── eventDemo.js└── utils.js
通过 type="module"
,我们可以创建一个清晰的模块系统,其中各个模块可以相互依赖,形成一层层的调用关系。浏览器能够智能地解析这些依赖关系,确保所有必要的模块都被正确加载和执行。这种方式不仅提高了代码的可维护性和复用性,还允许开发者利用现代JavaScript的强大功能来构建更加复杂的应用程序。
./utils.js
export function printLog(msg){console.log(msg);
}
8.2 export
关键字
export
关键字:允许你将函数、变量或类从当前模块中暴露出去,以便其他模块可以通过import
语句来使用它们。- 在这段代码中,
printLog
函数被定义并立即通过export
关键字导出,这意味着任何导入此模块的地方都可以访问到printLog
函数。
./js/eventDemo.js
import { printLog } from "./utils.js";//click: 鼠标点击事件
document.querySelector('#b2').addEventListener('click', () => {printLog("我被点击了...");
})//mouseenter: 鼠标移入
document.querySelector('#last').addEventListener('mouseenter', () => {printLog("鼠标移入了...");
})//mouseleave: 鼠标移出
document.querySelector('#last').addEventListener('mouseleave', () => {printLog("鼠标移出了...");
})//keydown: 某个键盘的键被按下
document.querySelector('#username').addEventListener('keydown', () => {printLog("键盘被按下了...");
})//keyup: 某个键盘的键被抬起
document.querySelector('#username').addEventListener('keyup', () => {printLog("键盘被抬起了...");
})//blur: 失去焦点事件
document.querySelector('#age').addEventListener('blur', () => {printLog("失去焦点...");
})//focus: 元素获得焦点
document.querySelector('#age').addEventListener('focus', () => {printLog("获得焦点...");
})//input: 用户输入时触发
document.querySelector('#age').addEventListener('input', () => {printLog("用户输入时触发...");
})//submit: 提交表单事件
document.querySelector('form').addEventListener('submit', () => {alert("表单被提交了...");
})
8.3 import
关键字
import
语句:用来从其他模块导入所需的函数、对象或原始值。这里的import { printLog } from "./utils.js";
是从./utils.js
文件中导入一个名为printLog
的函数。{}
花括号:表示只导入特定的导出项。如果要导入整个模块的所有导出项,可以省略花括号并使用星号*
加上一个别名,例如import * as utils from "./utils.js";
。
8.4 常见事件
8.4.1 鼠标事件
click
: 当用户点击某个元素时触发,是最常用的鼠标事件之一。dblclick
: 双击事件。mouseover
和mouseout
: 分别当鼠标指针进入和离开元素时触发。mousedown
和mouseup
: 分别在按下和释放鼠标按钮时触发。
8.4.2 键盘事件
keydown
和keyup
: 分别在按键被按下和释放时触发。keypress
: 当字符键被按下时触发(已废弃,在现代开发中不推荐使用)。
8.4.3 表单事件
submit
: 当用户提交表单时触发。可以用来验证表单数据或阻止默认的提交行为。input
和change
: 分别在输入框内容变化时(实时)和失去焦点时触发,适用于表单元素如文本框、下拉列表等。focus
和blur
: 分别在元素获得焦点和失去焦点时触发。
8.4.4 焦点事件
focusin
: 当元素即将获得焦点时触发,并且此事件会冒泡。可以在父级元素上监听focusin来响应任何子元素获得焦点的情况。focus
: 当用户通过点击、键盘导航或脚本使一个元素获得焦点时触发。常用于表单元素如输入框、文本区域等,以检测用户的交互。blur
: 当元素失去焦点时触发。与focus事件相对,它标志着用户已经结束了对该元素的操作或离开了该元素。
8.4.5 其他事件
load
: 页面加载完成后触发。resize
: 窗口大小改变时触发。scroll
: 页面滚动时触发。
二、Vue
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,旨在通过简洁的 API 实现响应式的数据绑定和组件化的视图管理。它允许开发者创建可复用的组件,并通过声明式渲染将数据动态地绑定到DOM元素上。Vue 的核心库专注于视图层,但其生态系统包括了路由(Vue Router)、状态管理(Vuex)等强大工具,支持从简单的单页面应用到复杂的大规模应用开发。Vue 以其易学易用、灵活性高和性能优越而著称,使其成为现代前端开发中非常受欢迎的选择。与传统的 MVC 框架相比,Vue 更加轻量且易于集成到现有项目中。
1. Vue快速入门
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue-快速入门</title>
</head>
<body><div id="app"><h1>{{message}}</h1><h1>{{count}}</h1></div><script type="module">import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';createApp({data() {return {message: 'Hello Vue',count: 100}}}).mount('#app');</script>
</body>
</html>
1.1 数据绑定
- 插值表达式:
- 使用双大括号语法
{{ }}
绑定数据属性到HTML中。例如,<h1>{{ message }}</h1>
会显示message
的值。
- 使用双大括号语法
1.2 模块化脚本加载
- ES模块:
- 使用
<script type="module">
标签来加载脚本,并通过import
语句从CDN引入Vue 3库文件。
- 使用
1.3 响应式数据
- 响应式数据对象:
- 在
data()
方法中返回的对象中的所有属性都是响应式的。这意味着当这些属性的值发生变化时,Vue会自动更新相关的视图部分。
- 在
1.4 应用实例创建与挂载
- 创建Vue应用实例:
- 使用
createApp({...})
创建一个新的Vue应用实例,并通过.mount('#app')
将其挂载到指定的DOM元素上。
- 使用
2. Vue生命周期
Vue 的生命周期是指 Vue 实例从创建到销毁所经历的一系列阶段。每个阶段都有特定的钩子函数(Lifecycle Hooks),允许开发者在这些关键点插入自定义逻辑,如初始化数据、响应状态变化或清理资源等。理解 Vue 的生命周期对于开发高效且可维护的应用至关重要。
2.1 Vue生命周期的主要阶段
2.1.1 创建阶段 (Creation)
beforeCreate
:实例刚刚被创建,但尚未开始初始化属性(如data
和methods
)。此时,实例还不能访问 DOM 或者响应式数据。created
:实例已完成数据观测和事件配置,但尚未挂载到 DOM 上。这是发起网络请求、设置定时器或执行其他初始化操作的好时机。
2.1.2 挂载阶段 (Mounting)
beforeMount
:模板编译完成,虚拟 DOM 创建完毕,但还没有渲染到真实 DOM 中。可以在这个阶段做一些准备工作,比如预加载资源。mounted
:实例已经被挂载到真实的 DOM 中,所有的指令和组件都已经解析并应用。现在你可以安全地操作 DOM 元素了。这也是一个常用的钩子来启动动画效果或与第三方库集成。
2.1.3 更新阶段 (Updating)
beforeUpdate
:当响应式数据发生变化时触发,但在新旧 DOM 被替换之前。这里适合进行一些基于旧状态的操作。updated
:DOM 已经根据最新的数据进行了更新。需要注意的是,在这个钩子中再次修改状态可能会导致无限循环的更新。
2.1.4 销毁阶段 (Destroying)
beforeUnmount
:实例即将被销毁,所有绑定的事件监听器和子组件都将被移除,但此时实例仍然完全可用。可以在此处执行清理工作,例如取消订阅外部服务或清除定时器。unmounted
:实例已经完全销毁,所有相关的资源都被释放。之后不能再访问该实例。
2.2 生命周期图示
下图展示了 Vue 实例的生命周期:
+-------------------+ +-------------------+
| beforeCreate | ----> | created |
+-------------------+ +-------------------+| |v v
+-------------------+ +-------------------+
| beforeMount | ----> | mounted |
+-------------------+ +-------------------+| |v v
+-------------------+ +-------------------+
| beforeUpdate | <---- | updated |
+-------------------+ +-------------------+| |v v
+-------------------+ +-------------------+
| beforeUnmount | ----> | unmounted |
+-------------------+ +-------------------+
2.3 使用场景
- 数据初始化:可以在
created
阶段进行数据的初始化,例如发起网络请求获取初始数据。 - DOM 操作:利用
mounted
阶段进行需要 DOM 元素的操作,比如绑定事件监听器。 - 清理工作:在
beforeUnmount
阶段执行一些清理工作,如清除定时器、取消订阅等。
三、Axios
Axios 是一个基于 Promise 的 HTTP 客户端,适用于浏览器和 Node.js,用于发起异步 HTTP 请求。它提供了简洁的 API 来处理请求和响应,并支持诸如拦截请求和响应、自动转换 JSON 数据等功能。与传统的 AJAX(通过 XMLHttpRequest 实现)相比,Axios 更加现代化且易于使用,减少了样板代码并提高了可读性。
1. Axios快速入门
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax-Axios</title>
</head>
<body><input type="button" value="获取数据GET" id="btnGet"><input type="button" value="操作数据POST" id="btnPost"><script src="js/axios.js"></script><script>//发送GET请求document.querySelector('#btnGet').addEventListener('click', () => {//axios发起异步请求axios({url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/list',method: 'GET'}).then((result) => { //成功回调函数console.log(result.data);}).catch((err) => { //失败回调函数console.log(err);})})//发送POST请求document.querySelector('#btnPost').addEventListener('click', () => {//axios发起异步请求axios({url: 'https://mock.apifox.cn/m1/3083103-0-default/emps/update',method: 'POST',data: 'id=1' //POST请求方式 , 请求体}).then((result) => { //成功回调函数console.log(result.data);}).catch((err) => { //失败回调函数console.log(err);})})</script>
</body>
</html>
1.1 Axios GET请求
- 当用户点击“获取数据GET”按钮时,将触发一个GET请求,从指定URL
https://mock.apifox.cn/m1/3083103-0-default/emps/list
获取数据。 - 请求成功后,结果会打印在控制台上。
1.2 Axios POST请求
- 当用户点击“操作数据POST”按钮时,将触发一个POST请求到
https://mock.apifox.cn/m1/3083103-0-default/emps/update
。 - 在这个例子中,POST请求携带的数据为
'id=1'
,表示这是一个简单的键值对数据。 - 同样地,如果请求成功,结果也会打印在控制台上。
1.3 回调函数
- 成功回调函数 (
then
): 处理成功的请求,提供对响应数据的访问。 - 失败回调函数 (
catch
): 处理请求中的错误,帮助识别和处理不同类型的错误。
2. Axios请求方式别名
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ajax-Axios</title>
</head>
<body><input type="button" value="获取数据GET" id="btnGet"><input type="button" value="操作数据POST" id="btnPost"><script src="js/axios.js"></script><script>//发送GET请求document.querySelector('#btnGet').addEventListener('click', () => {axios.get('https://mock.apifox.cn/m1/3083103-0-default/emps/list').then((result) => {console.log(result.data);});console.log('==========================');})//发送POST请求document.querySelector('#btnPost').addEventListener('click', () => {axios.post('https://mock.apifox.cn/m1/3083103-0-default/emps/update', 'id=1').then((result) => {console.log(result.data);});})</script>
</body>
</html>
Axios 提供了多种请求方式的别名方法,使开发者能够方便地发送不同类型的HTTP请求。通过使用这些别名方法,可以简化代码并提高可读性。以下是常见的请求方式别名及其用途:
axios.get(url[, config])
: 发送GET请求。axios.post(url[, data[, config]])
: 发送POST请求。axios.put(url[, data[, config]])
: 发送PUT请求。axios.delete(url[, config])
: 发送DELETE请求。axios.head(url[, config])
: 发送HEAD请求。axios.options(url[, config])
: 发送OPTIONS请求。axios.patch(url[, data[, config]])
: 发送PATCH请求。
四、案例—员工列表
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>Tlias智能学习辅助系统</title><style>/* 导航栏样式 */.navbar {background-color: #b5b3b3; /* 灰色背景 */display: flex; /* flex弹性布局 */justify-content: space-between; /* 左右对齐 */padding: 10px; /* 内边距 */align-items: center; /* 垂直居中 */}.navbar h1 {margin: 0; /* 移除默认的上下外边距 */font-weight: bold; /* 加粗 */color: white;/* 设置字体为楷体 */font-family: "楷体";}.navbar a {color: white; /* 链接颜色为白色 */text-decoration: none; /* 移除下划线 */}/* 搜索表单样式 */.search-form {display: flex;flex-wrap: nowrap;align-items: center;gap: 10px; /* 控件之间的间距 */margin: 20px 0;}.search-form input[type="text"], .search-form select {padding: 5px; /* 输入框内边距 */width: 260px; /* 宽度 */}.search-form button {padding: 5px 15px; /* 按钮内边距 */}/* 表格样式 */table {width: 100%;border-collapse: collapse;}th, td {border: 1px solid #ddd; /* 边框 */padding: 8px; /* 单元格内边距 */text-align: center; /* 左对齐 */}th {background-color: #f2f2f2;font-weight: bold;}.avatar {width: 30px;height: 30px;}/* 页脚样式 */.footer {background-color: #b5b3b3; /* 灰色背景 */color: white; /* 白色文字 */text-align: center; /* 居中文本 */padding: 10px 0; /* 上下内边距 */margin-top: 30px;}#container {width: 80%; /* 宽度为80% */margin: 0 auto; /* 水平居中 */}</style>
</head>
<body><div id="container"><!-- 顶部导航栏 --><div class="navbar"><h1>Tlias智能学习辅助系统</h1><a href="#">退出登录</a></div><!-- 搜索表单区域 --><form class="search-form"><label for="name">姓名:</label><input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名"><label for="gender">性别:</label><select id="gender" name="gender" v-model="searchForm.gender"><option value=""></option><option value="1">男</option><option value="2">女</option></select><label for="position">职位:</label><select id="position" name="position" v-model="searchForm.job"><option value=""></option><option value="1">班主任</option><option value="2">讲师</option><option value="3">学工主管</option><option value="4">教研主管</option><option value="5">咨询师</option></select><button type="button" v-on:click="search">查询</button><button type="button" @click="clear">清空</button></form><!-- 表格展示区 --><table><!-- 表头 --><thead><tr><th>序号</th><th>姓名</th><th>性别</th><th>头像</th><th>职位</th><th>入职日期</th><th>最后操作时间</th><th>操作</th></tr></thead><!-- 表格主体内容 --><tbody><tr v-for="(e, index) in empList" :key="e.id"><td>{{index + 1}}</td><td>{{e.name}}</td><td>{{e.gender == 1?'男' : '女'}}</td><!-- 插值表达式是不能出现在标签内部 --><td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td><!-- v-if: 控制元素的显示与隐藏 --><td><span v-if="e.job == 1">班主任</span><span v-else-if="e.job == 2">讲师</span><span v-else-if="e.job == 3">学工主管</span><span v-else-if="e.job == 4">教研主管</span><span v-else-if="e.job == 5">咨询师</span><span v-else>其他</span></td><!-- v-show: 控制元素的显示与隐藏 --><!-- <td><span v-show="e.job == 1">班主任</span><span v-show="e.job == 2">讲师</span><span v-show="e.job == 3">学工主管</span><span v-show="e.job == 4">教研主管</span><span v-show="e.job == 5">咨询师</span></td> --><td>{{e.entrydate}}</td><td>{{e.updatetime}}</td><td class="action-buttons"><button type="button">编辑</button><button type="button">删除</button></td></tr></tbody></table><!-- 页脚版权区域 --><footer class="footer"><p>江苏传智播客教育科技股份有限公司</p><p>版权所有 Copyright 2006-2024 All Rights Reserved</p></footer></div><script src="js/axios.js"></script><script type="module">import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'createApp({data() {return {searchForm: { //封装用户输入的查询条件name: '',gender: '',job: ''},empList: []}},//方法methods: {async search(){// 发送ajax请求,获取数据// axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`).then((result) => {// this.empList = result.data.data;// })// console.log('===========================');let result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);this.empList = result.data.data;},clear(){//清空表单项数据this.searchForm = {name:'', gender:'', job:''}this.search()}},//钩子函数mounted(){//页面加载完成之后,发送ajax请求,获取数据this.search()}}).mount('#container')</script></body>
</html>
https://web-server.itheima.net/emps/list
{"code": 1,"msg": "success","data": [{"id": 1,"name": "谢逊","image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/4.jpg","gender": 1,"job": 1,"entrydate": "2023-06-09","updatetime": "2023-07-01 00:00:00"},{"id": 2,"name": "韦一笑","image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg","gender": 1,"job": 1,"entrydate": "2023-06-09","updatetime": "2023-07-01 00:00:00"},{"id": 3,"name": "黛绮丝","image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/2.jpg","gender": 2,"job": 2,"entrydate": "2023-06-09","updatetime": "2023-07-01 00:00:00"},{"id": 4,"name": "殷天正","image": "https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/3.jpg","gender": 1,"job": 3,"entrydate": "2023-06-09","updatetime": "2023-07-01 00:00:00"}]
}
根据你提供的代码,以下是关于Vue的关键知识点总结,包括searchForm
、v-model
、v-on
、v-if
、v-for
、async
和await
的详细解释:
1. Vue 关键知识点总结
1.1 searchForm
对象
- 用途: 封装用户在搜索表单中输入的查询条件。
- 定义:
data() {return {searchForm: { // 封装用户输入的查询条件name: '',gender: '',job: ''},empList: []} }
- 作用: 在Vue实例的数据对象中定义
searchForm
,用于存储用户的输入值,并通过v-model
指令将其与表单元素绑定。
1.2 v-model
指令
- 用途: 实现双向数据绑定,将表单元素的值与Vue实例中的数据属性同步。
- 示例:
<input type="text" id="name" name="name" v-model="searchForm.name" placeholder="请输入姓名"> <select id="gender" name="gender" v-model="searchForm.gender"><option value=""></option><option value="1">男</option><option value="2">女</option> </select> <select id="position" name="position" v-model="searchForm.job"><option value=""></option><option value="1">班主任</option><option value="2">讲师</option><!-- 其他选项 --> </select>
- 作用: 当用户在表单元素中输入或选择内容时,
v-model
会自动更新对应的Vue实例数据属性;反之亦然。
1.3 v-on
指令
- 用途: 绑定事件监听器,处理用户的交互行为。
- 示例:
<button type="button" v-on:click="search">查询</button> <button type="button" @click="clear">清空</button>
- 作用:
v-on:click="search"
:当点击按钮时,调用search
方法。@click="clear"
:简写形式,功能同上。@
是v-on:
的缩写。
1.4 v-if
和 v-else-if
指令
- 用途: 条件渲染,根据表达式的值决定是否渲染元素。
- 示例:
<td><span v-if="e.job == 1">班主任</span><span v-else-if="e.job == 2">讲师</span><span v-else-if="e.job == 3">学工主管</span><span v-else-if="e.job == 4">教研主管</span><span v-else-if="e.job == 5">咨询师</span><span v-else>其他</span> </td>
- 作用: 根据
e.job
的值,显示相应的职位名称。如果e.job
为1,则显示“班主任”,依此类推。
好的,让我们通过你提供的注释代码片段来详细解释 v-show
指令,并说明它与 v-if
的区别。
1.5 v-show
指令
- 用途: 根据表达式的值动态地显示或隐藏元素。
- 示例:
<td><span v-show="e.job == 1">班主任</span><span v-show="e.job == 2">讲师</span><span v-show="e.job == 3">学工主管</span><span v-show="e.job == 4">教研主管</span><span v-show="e.job == 5">咨询师</span> </td>
- 作用: 通过 CSS 的 display 属性控制元素的显示和隐藏,适用于需要频繁切换显示状态的场景。
1.6 v-show
与 v-if
的区别
-
v-show
:- 只是通过 CSS 的
display
属性来控制元素的显示和隐藏。 - 元素始终存在于 DOM 中,只是在需要时通过
display: none;
来隐藏。 - 适用于需要频繁切换显示状态的场景,因为其性能开销较小。
- 只是通过 CSS 的
-
v-if
:- 根据条件决定是否渲染元素到 DOM 中。
- 如果条件为假,元素将不会被渲染到 DOM 中;如果条件为真,则会渲染。
- 适用于不经常切换显示状态的场景,因为它涉及到 DOM 的增删操作,性能开销较大。
1.7 v-for
指令
- 用途: 列表渲染,用于循环生成DOM元素。
- 示例:
<tr v-for="(e, index) in empList" :key="e.id"><td>{{index + 1}}</td><td>{{e.name}}</td><td>{{e.gender == 1 ? '男' : '女'}}</td><td><img class="avatar" v-bind:src="e.image" :alt="e.name"></td><!-- 职位显示部分 --><td>{{e.entrydate}}</td><td>{{e.updatetime}}</td><td class="action-buttons"><button type="button">编辑</button><button type="button">删除</button></td> </tr>
- 作用: 遍历
empList
数组,为每个员工生成一行表格数据。:key="e.id"
确保每个元素都有一个唯一的标识符,便于Vue进行高效的DOM更新。
1.8 async
和 await
- 用途: 处理异步操作,使代码看起来更简洁和易于理解。
- 示例:
methods: {async search(){let result = await axios.get(`https://web-server.itheima.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}`);this.empList = result.data.data;},clear(){this.searchForm = {name:'', gender:'', job:''};this.search();} }, mounted(){this.search(); }
- 作用:
async search()
:定义一个异步函数,允许使用await
关键字等待异步操作完成。let result = await axios.get(...)
:等待axios.get
请求完成,并将结果赋值给result
变量。mounted()
钩子函数:在组件挂载完成后自动调用search
方法,加载初始数据。
1.9 URL 解释
https://web-server.itheika.net/emps/list?name=${this.searchForm.name}&gender=${this.searchForm.gender}&job=${this.searchForm.job}
1.9.1 基础URL
https://web-server.itheima.net/emps/list
: 这是API的端点,用于获取员工列表数据。
1.9.2 查询参数
-
?
: 表示开始传递查询参数。 -
name=${this.searchForm.name}
:name
是查询参数名。${this.searchForm.name}
是用户在搜索表单中输入的姓名。例如,如果用户输入“张三”,则这部分变为name=张三
。
-
&
: 分隔不同的查询参数。 -
gender=${this.searchForm.gender}
:gender
是查询参数名。${this.searchForm.gender}
是用户选择的性别。例如,如果用户选择“男”(假设值为1),则这部分变为gender=1
。
-
job=${this.searchForm.job}
:job
是查询参数名。${this.searchForm.job}
是用户选择的职位。例如,如果用户选择“班主任”(假设值为1),则这部分变为job=1
。