当前位置: 首页 > news >正文

零基础一篇打通Vue极速通关教程

文章目录

  • 写给零基础看的Vue极速掌握教程
  • 第1章 Vue简介
    • 1.1 Vue 概述
    • 1.2 MVVM 模式
    • 1.3 WebStorm开发工具
      • 1.3.1 WebStorm简介
      • 1.3.2 集成Vue开发调试工具
  • 第2章 Vue的事件绑定
    • 2.1 Vue基本使用
      • 2.1.1 插值表达式
      • 2.1.2 注意事项
    • 2.2 Vue事件绑定
      • 2.1.1 点击事件
      • 2.2.2 键盘事件
      • 2.2.3 移动事件
    • 2.3 按键修饰符
      • 2.3.1 默认的按键修饰符
      • 2.3.2 自定义按键修饰符
      • 2.3.3 自定义按键修饰符注意事项
      • 2.3.4 自定义别名
    • 2.4 事件修饰符
  • 第3章 Vue常用指令
    • 3.1 v-text与v-html
    • 3.2 v-for
    • 3.3 v-if与v-show
    • 3.4 MVVM双向绑定
      • 3.4.1 v-bind
      • 3.4.2 v-model
  • 第4章 Vue的生命周期
    • 4.1 Vue的生命周期简介
    • 4.2 Vue的生命周期钩子
      • 4.2.1 beforeCreate/created
      • 4.2.2 beforeMount/mounted
      • 4.2.3 beforeUpdate/updated
      • 4.2.4 beforeDestory/destroyed
  • 第5章 Vue的ajax
    • 5.1 vue-resource
    • 5.2 Promise
      • 5.2.1 回调地狱
      • 5.2.2 Promise的使用
      • 5.2.3 Promise改造Ajax请求
    • 5.2 axios
      • 5.2.1 搭建WEB工程
      • 5.2.2 使用axios发送请求
    • 5.3 axios配置
    • 5.4 axios拦截器

写给零基础看的Vue极速掌握教程

第1章 Vue简介

1.1 Vue 概述

是一套用于构建用户界面渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定以及组合视图组件

Vue3官网:https://cn.vuejs.org/

Vue2官网:https://v2.cn.vuejs.org/

1.2 MVVM 模式

MVVM(Model-View-ViewModel)即:模型-视图-视图模型,是一种软件架构设计模式,常用于简化用户界面的开发。其核心在于将数据模型(Model)和视图(View)之间的交互抽象化,通过一个称为ViewModel的组件来实现。ViewModel负责将Model中的数据转换成视图可以使用的格式,并且暴露给视图操作的数据和命令。

ViewModel 需要做两件事情:

(1)需要监听Model的数据变化,将Model上的任何数据变化渲染到View上。

(2)需要监听View上的任何数据变化,将View上的任何变动写入Model中。

  • Model:后端响应的数据,前端将其使用Model接收(封装)
  • View:我们看到的各种HTML控件,负责使用HTML控件来渲染已经得到的数据。
  • ViewModel:将后端响应的数据(Model)绑定(渲染)到视图(View)中,其次,当视图控件进行数据修改时,VM能监听到数据的修改,将用户更新的数据直接更新到Model中。

Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel 负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

我们可以回顾一下之前的原生JS/JQ代码是如何渲染数据的:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title></head><body><!-- View: 视图 --><select name="" id="depts"></select></body></html><script type="text/javascript">$.get("/dept/findAll",function(res){				// res: 后端响应的数据(Model)var deptHtml="";for(var dept of res){				deptHtml+="<option value="+dept.id+">"+dept.name+"</option>";}// 更新视图(View)$("#depts").html(deptHtml);})
</script>

1.3 WebStorm开发工具

1.3.1 WebStorm简介

WebStorm 是JetBrains 公司旗下一款 JavaScript 开发工具。已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

1.3.2 集成Vue开发调试工具

vue-devtools是一款基于chrome游览器的插件,用于调试vue应用,这可以极大地提高我们的调试效率。在Edge浏览器的地址栏上输入"edge://extensions/",回车,进入Edge浏览器全局设置页面,如图所示。

点击“获取 Microsoft Edge 扩展”,搜索“vue devtools”,如图所示。

编写一个Vue案例:

<!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>Document</title><script src="./js/vue.js"></script></head><body><div id="app">{{msg}}</div></body><script>new Vue({el: "#app",data: {msg: "hello Vue!"}})
</script></html>

按下F12,打开浏览器的控制台,可以观察Vue插件。

发现多了一个Vue调试工具的菜单栏;

第2章 Vue的事件绑定

2.1 Vue基本使用

Vue.js 是一个用于构建用户界面的渐进式JavaScript框架。它提供了一套声明式的渲染数据到DOM的系统(其底层依赖于Vue提供的VM组件),以及组件化的开发模式。Vue.js 通过指令来扩展HTML的功能,使得开发者能够以声明式的方式将DOM的绑定至底层Vue实例的数据上。

2.1.1 插值表达式

Vue.js 中的插值表达式是一种简洁的方式,用来在模板中显示数据模型的变化。最常用的插值表达式是双大括号 {{ }},它可以插入数据模型中变量的值。

  • 使用示例:

当在模板中使用双大括号 {{ }} 包裹一段表达式时,Vue 会计算这段表达式的值,并将其转换为字符串然后插入到 DOM 中。例如:

<span>{{ message }}</span>

如果 Vue 实例的数据(data)中有 message 属性,那么该属性的值将被渲染到页面上。

插值表达式中可以包含任何有效的 JavaScript 表达式,包括变量引用、字符串连接、算术运算等。

例如:

<p>{{ firstName + ' ' + lastName }}</p><p>{{ 1 + 2 }}</p><p>{{ ok ? 'YES' : 'NO' }}</p>

小练习:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title></title><script src="js/vue.min.js" type="text/javascript" charset="utf-8"></script></head><body><!-- 准备一个容器 --><div id="box"><h3>number:{{number}}</h3><h3>message:{{message}}</h3><h3>flag:{{flag}}</h3><h3>car:{{car}}</h3><h3>season:{{season}}</h3></div></body><script type="text/javascript">// 是否开启devtools调试工具(开发版本默认为true,生产版本默认为false)Vue.config.devtools = true;new Vue({ // 创建一个Vue实例el: "#box", // 通过id选择器选择某个控件(代码Vue接管这片区域)data: { // Vue中存放数据的地方(Model)number: 100,message: "Hello Vue!",flag: true,car: {brand: "长安汽车",name: "长安CS95",price: 158000},season: ["Spring", "Summer", "Autumn", "Winter"]}})</script></html>

2.1.2 注意事项

一个Vue只能绑定一个组件,即使选择器可以选择多个组件,那么也不会生效;

<body><div class="box">{{msg}}</div><div class="box">{{msg}}</div><script type="text/javascript">new Vue({el: ".box",				// 通过class选择器选择组件data: {msg:"Hello Vue!"}})</script></body>

当然,我们也可以创建多个Vue实例来接管多个组件。

<body>
<div id="box1">{{msg}}
</div><div id="box2">{{msg}}
</div><script type="text/javascript">new Vue({el: "#box1",				// 通过class选择器选择组件data: {msg:"Hello Vue!"}})new Vue({el: "#box2",				// 通过class选择器选择组件data: {msg:"Hello Vue!"}})
</script></body>

2.2 Vue事件绑定

在Vue中提供 v-on 命令用于监听 DOM 事件,并在事件触发时执行一些 JavaScript 代码。它可以在 Vue 模板中被用来响应用户操作,如点击按钮、输入文本等。可以直接在 HTML 元素上使用 v-on 指令来绑定一个事件监听器到这个元素上的某个事件上。最简单的形式是将一个方法名(字符串)作为表达式传入 v-on 指令。

  • 示例代码:
<button v-on:click="doSomething">点击我</button>

当用户点击按钮时,将会调用 Vue 实例中的 methods 属性里定义的 doSomething 方法。

  • 简写方式:

为了简化书写,Vue 还提供了一个简短的语法来代替完整的 v-on 写法。只需要使用 @ 符号加上事件名即可。

<button @click="doSomething">点击我</button>

vue提供的事件非常多,几乎支持所有的原生JS事件,采用v-on:的方式监听。常用的Vue事件如下。

事件类型描述
click当用户点击鼠标按钮时调用。
dblclick当用户双击鼠标按钮时调用。
mousedown当用户按下鼠标按钮时调用。
mouseup当用户释放鼠标按钮时调用。
mouseover当用户将鼠标指针移到元素上时调用。
mouseout当用户将鼠标指针从元素或其子元素移开时调用。
mouseenter当用户将鼠标指针移到元素上时调用(不包括子元素)。
mouseleave当用户将鼠标指针从元素或其子元素移开时调用。
contextmenu当用户右击(或执行类似操作)来打开上下文菜单时调用。
keydown当用户按下键盘上的键时调用。
keypress当用户按下一个或多个键并且产生字符值时调用。
keyup当用户释放键盘上的键时调用。
submit当表单提交时调用。
focus当元素获得焦点时调用。
blur当元素失去焦点时调用。
change当域的内容被改变时调用。
input每当输入字段发生变化时调用。
reset当表单被重置时调用。
select当用户选择一些文本或更改了对象的选择时调用。
touchstart触摸开始时调用。
touchmove触摸移动时调用。
touchend触摸结束时调用。
touchcancel触摸被中断时调用。

2.1.1 点击事件

点击事件分为单机事件与双击事件,在Vue中分别采用click和dbclick来监听。

  • v-on:click:单机事件。
  • v-dbclick:双击事件。

示例代码:

<body>
<div id="box"><h3>单击事件</h3><p><a href="http://www.baidu.com" v-on:click="fun1">我是按钮1</a></p><p><a href="http://www.baidu.com" v-on:click="fun2('hello')">我是按钮2</a></p><p><a href="http://www.baidu.com" v-on:click="fun3">我是按钮3</a></p><!-- v-on: 可以简写成@ --><!-- 如果event参数在后面,则必须显示的传递 --><p><a href="http://www.baidu.com" @click="fun4('hello',$event)">我是按钮4</a></p><h3>双击事件</h3><p><button v-on:dblclick="fun5">双击事件</button></p></div><script type="text/javascript">new Vue({el: "#box",data: {},methods:{fun1:function(){alert(1)},fun2:function(msg){alert(msg)},fun3:function(event){				// Vue中定义的方法默认会传递一个event事件alert(event)event.preventDefault();			// 阻止事件的默认行为(跳转页面)},fun4:function(msg,event){alert(msg);alert(event);},fun5:function(){alert("双击事件!")}}})
</script></body>

2.2.2 键盘事件

  • v-on:keydown:鼠标按下事件
  • v-on:keyup:鼠标抬起事件

示例代码:

<body><div id="box"><input type="text" v-on:keydown="down"><br> <!-- 键盘按下事件 --><input type="text" v-on:keyup="up"> <!-- 键盘抬起事件 --></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {down() { // 简写方式console.log("键盘按下了")},up(){console.log("键盘抬起了")}}})</script></body>

2.2.3 移动事件

  • v-on:mouseover:鼠标移入事件
  • v-on:mouseout:鼠标移出事件

示例代码:

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script></head><body><div id="box" style="width: 300px;height: 200px;background-color: gray;" v-on:mousemove="inter" v-on:mouseout="outer"></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {inter(){console.log("鼠标移入了")},outer(){console.log("鼠标移出了")}}})</script></body></html>

2.3 按键修饰符

2.3.1 默认的按键修饰符

当进行键盘事件的监听时,我们可以通过event事件中的keyCode或者key来判断按下的是哪一个键,从而进行针对性的处理;同时Vue也为一些常用的按键分配了按键修饰符(相当于别名),这样就可以更加方便的来监听指定的按键,Vue中常用的按键别名如下:

  • 回车 => enter
  • 删除 => delete(捕获“删除”和“退格”键)
  • 退出 => esc
  • 空格 => space
  • 换行 => tab(没有keyup事件,只有keydown事件)
  • 上 => up
  • 下 => down
  • 左 => left
  • 右 => right

示例代码:

<body><div id="box"><p><input type="text" v-on:keyup="fun1"></p><p><input type="text" v-on:keyup.enter="fun2">enter</p><p><input type="text" v-on:keyup.delete="fun3">delete</p><p><input type="text" v-on:keyup.esc="fun4">esc</p><p><input type="text" v-on:keydown.tab="fun5">tab</p></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1(event){console.log(event.keyCode,"---",event.key)},fun2(){console.log("您按下了回车!")},fun3(){console.log("您按下了delete!")},fun4(){console.log("您按下了esc!")},fun5(){console.log("您按下了tab!")}}})</script></body>

2.3.2 自定义按键修饰符

针对于Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为短横线命名

例如:CapsLock—>caps-lock

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script></head><body>
<div id="box"><p><input type="text" v-on:keyup="fun1"></p><p><input type="text" v-on:keyup.Control="fun2">ctrl</p><!-- 注意需要【短横线命名】--><p><input type="text" v-on:keyup.caps-lock="fun3">CapsLock</p><p><input type="text" v-on:keyup.delete="fun4">delete</p></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1(event) {console.log(event.keyCode, "---", event.key)},fun2() {console.log("您按下了ctrl!")},fun3() {console.log("您按下了CapsLock!")},fun4() {console.log("您按下了delete或backspace键!")}}})
</script></body></html>

2.3.3 自定义按键修饰符注意事项

Vue自定义的按键修饰符修饰系统修饰键(用法特殊)时:(ctrl、alt、shift、meta),其中ctrl键除外;

  • 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
  • 配合keydown使用:正常触发事件。

另外,例如某些键监听不了;因此我们一般都使用Vue自身提供的按键修饰符或者采用keyCode/key来判断用户按下的键;

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script></head><body><div id="box"><p><input type="text" v-on:keyup="fun1"></p><p><input type="text" v-on:keyup.Control="fun2">ctrl</p>		<p><input type="text" v-on:keyup.Alt="fun3">alt</p>				<!-- 监听keyup时需要按其他键才能触发事件 --><p><input type="text" v-on:keyup.Shift="fun4">shift</p>		<!-- 监听keyup时需要按其他键才能触发事件 --><p><input type="text" v-on:keyup.Meta="fun5">meta</p>			<!-- 监听keyup时需要按其他键才能触发事件 --><p><input type="text" v-on:keydown.0="fun6">0</p>				<!-- 只能监听数字0 --></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1(event){console.log(event.keyCode,"---",event.key)},fun2(){console.log("您按下了ctrl!")},fun3(){console.log("您按下了alt!")},fun4(){console.log("您按下了shift!")},fun5(){console.log("您按下了windows!")},fun6(){console.log("您按下了数字0!")}}})</script></body></html>

2.3.4 自定义别名

Vue支持根据keyCode来扩展自定义的按键,扩展的自定义按键解决了系统按键需要搭配其他键才能触发的问题(也有部分按键可能会有问题)

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script></head><body><div id="box"><p><input type="text" v-on:keyup="fun1"></p><p><input type="text" v-on:keyup.huiche="fun2">回车</p>		<p><input type="text" v-on:keyup.kongge="fun3">空格</p>		<p><input type="text" v-on:keyup.windows="fun4">windows</p>		</div><script type="text/javascript">Vue.config.keyCodes.huiche = 13 			Vue.config.keyCodes.kongge = 32 			Vue.config.keyCodes.windows = 91 			new Vue({el: "#box",data: {},methods: {fun1(event){console.log(event.keyCode,"---",event.key)},fun2(){console.log("您按下了回车")},fun3(){console.log("您按下了空格!")},fun4(){console.log("您按下了windows!")}}})</script></body></html>

2.4 事件修饰符

Vue中提供了简化了很多JS中的事件修饰符,Vue中的事件修饰符如下:

事件说明
prevent阻止默认事件;
stop阻止事件冒泡;
capture使用事件的捕获模式;
once事件只触发一次;
self只有event.target是当前操作的元素时才触发事件;
passive事件的默认行为立即执行,无需等待事件回调执行完毕;
left (2.2.0)只当点击鼠标左键时触发。
right(2.2.0)只当点击鼠标右键时触发。
middle(2.2.0)只当点击鼠标中键时触发。

(1)阻止默认事件。

<body>
<div id="box"><!--a标签的默认事件被阻止了,所以不会进行链接跳转--><h3>阻止默认事件</h3><p><a href="http://www.baidu.com" v-on:click.prevent="fun1">百度一下</a></p></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1() {alert("Hello Baidu")}}})
</script></body>

(2)阻止冒泡事件。

<body>
<div id="box"><!-- 先点击到blue,然后向上传递给上层的空间(red)--><h3>未阻止冒泡事件</h3><div v-on:click="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div><!--只有blue被触发时间了,不会向上传递事件,red不会触发点击事件--><h3>阻止冒泡事件</h3><div v-on:click="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click.stop="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1() {console.log("red")},fun2() {console.log("blue")}}})
</script></body>

(3)事件捕捉。

<body>
<div id="box"><!--先blue(先捕捉到),再red--><h3>未进行事件捕捉</h3><div v-on:click="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div><!--先bred(先捕捉到),再blue--><h3>进行了事件捕捉</h3><div v-on:click.capture="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1() {console.log("red")},fun2() {console.log("blue")}}})
</script></body>

(4)self修饰符。

<body>
<div id="box"><!-- 默认情况下,点击了blue事件会进行冒泡传递给red,但是用户并非实际点击red,而是冒泡传递过去的 --><h5>没有使用self修饰符</h5><div v-on:click="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div><h5>使用了self修饰符</h5><!-- 只有真正的点击自己时才触发事件,不接收冒泡传递过来的事件 --><div v-on:click.self="fun1" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun2" style="width: 100px;height: 100px;background-color: blue;"></div></div></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1(event) {console.log(event.target)},fun2(event) {console.log(event.target)}}})
</script></body>

(6)左、右、中键点击事件。

<body>
<div id="box"><h3>单击事件</h3><button v-on:click.left="fun1">单击左键</button><button v-on:click.right="fun2">单击右键</button><button v-on:click.middle="fun3">单击中键</button></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1() {console.log("您点击了左键")},fun2(event) {console.log("您点击了右键")event.preventDefault()  //阻止默认事件(浏览器右键菜单)},fun3() {console.log("您点击了中键")}}})
</script></body>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script><style>li {height: 100px;}</style></head><body style="height: 1000px;">
<div id="box"><h3>阻止默认事件</h3><p><a href="http://www.baidu.com" v-on:click.prevent="fun1">百度一下</a></p><h3>阻止事件冒泡</h3><div v-on:click="fun2" style="width: 150px;height: 150px;background-color: red;"><div v-on:click.stop="fun3" style="width: 100px;height: 100px;background-color: blue;"></div></div><h3>只触发一次事件</h3><p><button v-on:click.once="fun4">我是按钮</button></p><h5>事件捕获</h5><!-- 默认情况下,先进行事件冒泡,再进行事件捕获capture: 先进行事件捕获,在进行事件冒泡--><div v-on:click.capture="fun5('red')" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun6('blue')" style="width: 100px;height: 100px;background-color: blue;"></div></div><h5>self修饰符</h5><!-- 只有真正的点击自己时才触发事件(冒泡不能触发事件) --><div v-on:click.self="fun7" style="width: 150px;height: 150px;background-color: red;"><div v-on:click="fun8" style="width: 100px;height: 100px;background-color: blue;"></div></div><h5>passvie</h5><!-- 事件的默认行为立即执行,无需等待事件回调执行完毕; --><ul v-on:wheel.passvie="fun9" style="width: 200px;height: 200px;background-color: red;overflow: scroll;"><li>1</li><li>2</li><li>3</li><li>4</li></ul><h5>.left</h5><button v-on:click.left="fun10">left</button></div><script type="text/javascript">new Vue({el: "#box",data: {},methods: {fun1() {alert("Hello Baidu")},fun2() {alert("点击了大的div")},fun3() {alert("点击了小的div")},fun4() {console.log("按钮点击了")},fun5(color) {console.log(color)},fun6(color) {console.log(color)},fun7(event) {console.log(event.target)},fun8(event) {console.log(event.target)},fun9() {for (let i = 0; i < 100000; i++) {console.log('aaa')}},fun10() {console.log("left")}}})
</script></body></html>

第3章 Vue常用指令

3.1 v-text与v-html

  • v-text:不会渲染字符串里面的HTML内容
  • v-html:会渲染字符串里面的HTML内容
<body style="height: 1000px;">
<div id="box"><div v-text="txt"></div><div v-html="txt"></div></div><script type="text/javascript">new Vue({el: "#box",data: {txt: "<h1>Hello</h1>"}})
</script></body>

3.2 v-for

v-for指令用于遍历使用;

<body>
<div id="box"><h3>遍历数组</h3><ul><li v-for="(city,index) in cities">{{city}}---{{index}}</li></ul><h3>遍历对象</h3><ul><li v-for="(val,key) in book">{{key}}---{{val}}</li></ul><h3>遍历对象数组</h3><ul><!-- 遍历对象数组时,需要分配:key,取一个唯一且能标识这条记录的值(id) --><li v-for="(car,index) in cars" :key="car.id"><h3>index: {{index}}</h3><p>id:{{car.id}}</p><p>brand:{{car.brand}}</p><p>name:{{car.name}}</p></li></ul></div><script type="text/javascript">new Vue({el: "#box",data: {cities: ["广州","杭州","兰州","郑州","福州"],book:{id:1,name:"《Java核心技术》",price: 28.8},cars:[{id:1,brand:"比亚迪",name:"比亚迪F3"},{id:2,brand:"五菱",name:"红菱宏光S3"},{id:3,brand:"长安",name:"长安欧尚x7"}]}})
</script></body>

3.3 v-if与v-show

  • v-if:根据表达式的值来决定是否渲染元素(存不存在)
  • v-show:是根据表达式的值来决定是否显示(display:none)

示例代码:

<body>
<div id="app"><button @click="fun1">v-if效果</button><button @click="fun2">v-show效果</button><hr><!-- v-if决定元素是否存在DOM中--><span v-if="flag_if">小灰</span><hr><!-- v-show只是给元素添加了display:none样式,元素仍然存在DOM中--><span v-show="flag_show">xiaohui</span></div><script>new Vue({el: "#app",data: {flag_if: false,flag_show: false},methods: {fun1: function() {this.flag_if = !this.flag_if;},fun2: function() {this.flag_show = !this.flag_show;}}});
</script></body>

3.4 MVVM双向绑定

双向绑定是MVVM模式中的一个重要特性,它允许数据在Model和View之间自动同步。这意味着当Model中的数据改变时,这些变化会自动反映到视图上;同样地,当用户通过视图改变了数据,这些变化也会被同步到Model中。这种机制极大地减少了手动处理数据同步的代码量,并且使得应用程序更易于维护。

3.4.1 v-bind

v-bind 指令用于动态地将属性绑定到 Vue 实例的数据。当 Vue 实例的数据发生变化时,v-bind 会自动更新绑定的属性值。但是这种绑定是单向的,即 Vue 实例中的数据发生变化后能够即使更新到UI组件上,但是当UI组件上的数据发生变化时,并不能够及时更新到Vue实例上。

它可以用来绑定任何 HTML 属性,包括 class、style 以及其他标准属性,如下:

  • v-bind:src 用于绑定图片的 src 属性。
  • v-bind:class 可以根据条件绑定类名。
  • v-bind:style 用于动态设置样式。

示例代码:

<body>
<div id="app"><p v-bind:title="testTitle">绑定titlte属性</p><!-- v-bind:title可以简写成:title --><p :title="testTitle" :style="testStyle">绑定title和sytle属性</p><input type="text" :value="testValue"><hr><a :href="url" v-bind::color="testColor">百度一下</a><hr><!--插入值写法--><a v-bind={href:"http://www.baidu.com?id="+id}>百度一下</a><hr>
</div><script>new Vue({el: "#app",data: {testColor: "blue",testTitle: "我是通过v-bind绑定的title",testValue: "Hello",url: "http://www.baidu.com",id: 100,// 如果存在 - 必须使用驼峰命名或者使用''testStyle:{color:'red','font-weight':200}}});
</script></body>

3.4.2 v-model

v-model指令用于将Vue中的数据与组件中的数据进行双向绑定,当Vue中的数据发生变化时,立马会渲染到组件上,当组件上的值发生变化时,会立马更新到Vue中;这使得用户输入能够直接反映到数据模型中,同时数据模型的变化也能立即反映在表单输入上。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title></title><script src="js/vue.js" type="text/javascript" charset="utf-8"></script></head><body>
<div id="app"><input type="text" v-model:value="testValue">
</div><script>new Vue({el: "#app",data: {testValue:"aaa"}});
</script></body></html>

第4章 Vue的生命周期

4.1 Vue的生命周期简介

每个 Vue 实例在被创建之前都要经过一系列的初始化过程.

vue在生命周期中共有:beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeDestorydestroyed8个状态;

4.2 Vue的生命周期钩子

4.2.1 beforeCreate/created

  • beforeCreate:Vue生命周期的第一个函数,在Vue对象创建之前执行,初始化Vue自身的事件、注册Vue示例的生命周期函数等,在该阶段props、data、method都处于不可用状态;
    • 1)创建VUE对象之前执行
    • 2)data中的数据还未初始化
    • 3)el还未关联到对应的id(还未挂载DOM)
    • 4){{}}表达式中的内容还没更新(真实DOM还未渲染)
  • created:创建VUE对象之后执行,该阶段Vue示例已经被创建成功,初始化了props、data、methods等功能;但是Vue还未挂载dom元素(还未进行绑定)
    • 1)创建VUE对象之后执行
    • 2)data中的数据已经初始化
    • 3)el还未关联到对应的id
    • 4){{}}表达式中的内容还没更新(真实DOM还未渲染)

【示例代码1-观察dom的变化】

<body>
<div id="box">{{message}}
</div><script>new Vue({el: "#box",data: {message: 'Hello World'},// 在beforeCreate阶段的Vue,数据未初始化、dom未挂载、dom也未渲染beforeCreate: function () {console.log('创建vue实例前【beforeCreate】');console.log('data 数据:' + this.message);			// undefinedconsole.log('挂载的对象:' + this.$el);				// undefinedconsole.log('真实dom结构:' + document.getElementById('box').innerHTML);		// {{message}}console.log('------------------');},// 在created阶段的Vue,数据已经初始化、但dom未挂载、dom也未渲染created: function () {console.log('创建vue实例后【created】');console.log('data 数据:' + this.message);				// Hello Worldconsole.log('挂载的对象:' + this.$el);					// undefinedconsole.log('真实dom结构:' + document.getElementById('box').innerHTML);		// {{message}}console.log('------------------');}});
</script></body>

【示例代码2-调用Vue数据】

<body>
<div id="box">{{message}}
</div><script>new Vue({el: "#box",data: {message: 'Hello World'},methods: {method() {console.log("method running...");}},beforeCreate: function () {console.log('创建vue实例前【beforeCreate】');// Vue实例还未创建成功,不能调用this.method();// Vue实例还未创建成功,不能访问数据(undefined)console.log(this.message);console.log('------------------');},created: function () {console.log('创建vue实例后【created】');// Vue实例已经创建成功,可以调用Vue方法this.method();// Vue实例已经创建成功,可以访问数据console.log(this.message);console.log('------------------');}});
</script></body>

4.2.2 beforeMount/mounted

  • beforeMount:对象挂载之前执行,此时el已经关联到对应对象,但{{}}表达式还未加载(挂载了,但还没完全挂载)
    • 1)对象挂载之前执行
    • 2)data中的数据已经初始化
    • 3)el已经关联到对应对象(挂载了DOM)
    • 4){{}}表达式中的内容还没更新(真实DOM还未渲染)
  • mounted:对象挂载之后执行,此时{{}}表达已经加载,执行完mounted之后开始正常执行js代码
    • 1)对象挂载之后执行
    • 2)data中的数据已经初始化
    • 3)el已经关联到对应对象
    • 4){{}}表达式中的内容已经更新(真实DOM已经渲染)

【示例代码1-观察dom的变化】

<body>
<div id="box">{{message}}
</div><script>var vm = new Vue({el: "#box",data: {message: 'Hello World'},// 在beforeMount阶段的Vue,数据已经初始化、dom已经挂载、但dom未渲染beforeMount: function () {console.log('挂载到dom前【beforeMount】');console.log('data 数据:' + this.message);			// Hello Worldconsole.log('挂载的对象:' + this.$el);				// [object HTMLDivElement]console.log('真实dom结构:' + document.getElementById('box').innerHTML);		// {{message}}console.log('------------------');},// 在mounted阶段的Vue,数据已经初始化、dom已经挂载、dom也已经渲染mounted: function () {console.log('挂载到dom后【mounted】');console.log('data 数据:' + this.message);			// Hello Worldconsole.log('挂载的对象:' + this.$el);				// [object HTMLDivElement]console.log('真实dom结构:' + document.getElementById('box').innerHTML);		// Hello Worldconsole.log('------------------');}});
</script></body>

4.2.3 beforeUpdate/updated

当修改了Vue中的数据时将会触发beforeUpdate与updated方法。

  • beforeUpdate:Vue数据更新前执行,此时data中的数据已经更新,但是{{}}表达式中引用的还没有更新(还未渲染到DOM上)。
  • updated:Vue数据更新后执行,{{}}表达式中引用也更新。

【示例代码-观察数据变更前后的值】

<body>
<div id="box">{{message}}<br><button v-on:click="fun1()">改变数据</button></div><script>var vm = new Vue({el: "#box",data: {message: 'Hello World'},methods: {fun1() {this.message = Math.random();}},// 当修改了Vue中的数据时,beforeUpdate方法中的dom还是为渲染之前的,但Vue中的数据已经修改beforeUpdate: function () {console.log('数据变化更新前【beforeUpdate】');console.log('data 数据:' + this.message);console.log('挂载的对象:' + this.$el);console.log('真实dom结构:' + document.getElementById('box').innerHTML);console.log('------------------');},// 当修改了Vue中的数据时,updated方法中的dom已经更新为最新的数据updated: function () {console.log('数据变化更新后【updated】');console.log('data 数据:' + this.message);console.log('挂载的对象:' + this.$el);console.log('真实dom结构:' + document.getElementById('box').innerHTML);console.log('------------------');}});</script></body>

4.2.4 beforeDestory/destroyed

  • beforeDestory:vue对象销毁前执行,在该方法中,Vue中注册的组件、侦听器、事件监听等都处于可用状态,一般在此阶段释放其他资源
  • destroyed:vue对象销毁后执行,在该方法中,已经销毁了Vue中注册的组件、侦听器、事件监听等;

【示例代码-观察Vue实例销毁前后的变化】

<body>
<div id="box">{{message}}<hr><button @click="exit">销毁VM</button></div><script>var vm = new Vue({el: "#box",data: {message: 'Hello World'},methods: {exit(){// 销毁vmthis.$destroy()}},beforeDestroy: function () {console.log('--------beforeDestroy----------');},destroyed: function () {console.log('--------destroyed----------');}});
</script></body>

第5章 Vue的ajax

5.1 vue-resource

vue-resource是Vue.js的插件提供了使用XMLHttpRequest或JSONP进行Web请求和处理响应的服务。 曾经是 Vue 社区广泛使用的库之一,用于发送 AJAX 请求和处理响应。当vue更新到2.0之后,作者就宣告不再对vue-resource更新,并且 Vue 官方推荐使用其他更现代的库来处理 HTTP 请求,如 Axios 或者原生的 Fetch API等。

5.2 Promise

Promise 是 JavaScript 中的一种编程模式,用于处理异步操作。它提供了一种更加优雅的方式来组织异步代码,避免了回调地狱(callback hell)的问题,并且使得错误处理更加一致。Promise 对象代表了一个最终会在未来完成(或失败)的异步操作,所以在 Promise 返回给调用者的时候,操作往往还没有完成,并且其结果值未知。

5.2.1 回调地狱

  • 回调函数:当一个函数作为参数传入另一个参数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执行,这种函数就称为回调函数。我们熟悉的定时器和Ajax中就存在有回调函数:
 //function(){console.log('执行了回调函数')}就是回调函数,它只有在3秒后才会执行
setTimeout(function(){  console.log('执行了回调函数');
},3000)  //3000毫秒
  • 异步任务:与之相对应的概念是“同步任务”,同步任务在主线程上排队执行,只有前一个任务执行完毕,才能执行下一个任务。异步任务不进入主线程,而是进入异步队列,前一个任务是否执行完毕不影响下一个任务的执行。同样,还拿定时器作为异步任务举例:
setTimeout(function(){console.log('执行了回调函数');
},3000)
console.log('111');

上述代码的实际输出顺序为:“111”、“执行了回调函数”。

  • 回调地狱:

根据前面我们可以得出一个结论:存在异步任务的代码,不能保证能按照顺序执行,那如果我们非要代码顺序执行呢?比如我需要先输出“First”,再输出“Second”,再输出“Third”。我必须要这样操作,才能保证顺序正确:

setTimeout(function () {console.log("First");setTimeout(function () {console.log("Second");setTimeout(function () {console.log("Third");}, 3000);}, 4000);
}, 1000);

可以看到,代码中的回调函数套回调函数,居然套了3层,这种回调函数中嵌套回调函数的情况就叫做回调地狱。实际上,回调地狱的场景还是挺多见的,我们经常需要先发送一段请求查询到某些数据以当做参数传递给下一个请求,这样下一个请求就必须等上一个请求完毕后才能执行。

5.2.2 Promise的使用

Promise 构造函数接受一个函数作为参数,该函数会被立即执行,所以我们称之为起始函数。起始函数包含两个函数 resolve 和 reject,分别表示 Promise 成功和失败的状态。

起始函数执行成功时,它应该调用 resolve 函数并传递成功的结果。当起始函数执行失败时,它应该调用 reject 函数并传递失败的原因。

Promise 构造函数返回一个 Promise 对象,该对象具有以下几个方法:

  • then:用于处理 Promise 成功状态的回调函数。
  • catch:用于处理 Promise 失败状态的回调函数。
  • finally:无论 Promise 是成功还是失败,都会执行的回调函数。

示例代码:

// 创建一个 Promise 对象
const promise = new Promise(function(resolve, reject) {// 进行异步操作,该setTimeout函数在创建Promise对象时就已经执行setTimeout(() => {// 随机生成成功或失败if (Math.random() < 0.5) {// 如果成功(then)执行resolve方法console.log('准备执行resolve');resolve('success');} else {// 如果失败(catch)执行reject方法console.log('准备执行reject');reject('error');}}, 1000);
});// 注册成功和失败的回调函数
promise.then(function (result){// result的值为resolve方法传入的值console.log(result);
}).catch(function (error){// error的值为reject方法传入的值console.log(error);
}).finally(function (){// 无论成功或失败都会执行console.log('Promise对象执行完毕');
})console.log('程序执行完毕');      // 因为Promise对象是异步的,所以先输出

执行情况:

示例代码:

new Promise(function (resolve, reject) {var a = 0;var b = 0;if (b == 0)reject("除数不能为0");elseresolve(a / b);
}).then(function (value) {console.log("a / b = " + value);
}).catch(function (err) {console.log(err);
}).finally(function () {console.log("End");
});console.log('程序执行完毕');      // 因为Promise对象是异步的,所以先输出

执行情况:

有了Promise,接下来我们可以改造一下回调地狱中的代码了:

function print(delay, message) {return new Promise(function (resolve, reject) {setTimeout(function () {console.log(message);resolve();}, delay);});
}print(2000, "First").then(function () {return print(4000, "Second");
}).then(function () {print(3000, "Third");
});

Promise 对象一旦 Promise 被创建,它的状态会在“待定”(pending)、“兑现”(fulfilled)和“拒绝”(rejected)之间转变。状态一旦转变,就不会再变回之前的状态。

  • 待定状态(pedding):调用promise时(创建Promise对象时),一开始就呈现出等待状态,遇到resolve或者reject之前,都处于这个状态。
  • 兑现状态(fulfilled):在执行了resolve后,promise则会从待定状态变成兑现状态,后续会进入.then 的回调函数中。
  • 拒绝状态(rejected)在执行了reject后,promise状态会从待定状态变成拒绝状态,后续会进入.catch 的回调函数中。

5.2.3 Promise改造Ajax请求

Promise可以封装一个异步操作,不阻塞当前任务的执行,利用这个特点我们可以用来封装ajax请求,示例代码如下:

const promise = new Promise((resolve, reject) => {
// 执行异步操作(该方法在创建Promise对象时就已经执行)
if (/* 异步操作是否成功 */) {resolve(value);// 调用 resolve,代表 Promise 将返回成功的结果(其实就是调用then方法)} else {reject(error);// 调用 reject,代表 Promise 会返回失败结果(其实就是调用catch方法)}
});

示例:

let getRequest = function (url) {// 使用Promise对象封装一个ajax请求return new Promise((resolve, reject) => {$.ajax({url: url,type: "GET",success(result) {// 调用Promise的resolve方法resolve(result);},error(error) {// 调用Promise的reject方法reject(error);}});})
}// 模拟一个请求地址
var url = "https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json";getRequest(url).then(function (result){console.log(result);
}).catch(function (error){console.log(error);
})console.log("程序执行完毕");

5.2 axios

axios 是一个基于 promise 的 HTTP 客户端,用于浏览器和 node.js。它提供了一种现代化的方式来进行 HTTP 请求和接收响应,支持诸如拦截请求和响应、转换请求和响应数据、取消请求等功能。axios 的设计使其易于使用,并且它已经成为许多前端和后端开发者的首选库之一。

  • axios的github地址:https://github.com/axios/axios
  • axios官方文档:https://axios.nodejs.cn/docs/api_intro

axios的语法如表所示。

语法说明
axios(config)使用axios发送ajax请求
axios(url[, config])使用axios发送ajax请求
axios.request(config)使用axios发送ajax请求
axios.get(url[, config])发送get请求
axios.delete(url[, config])发送delete请求
axios.head(url[, config])发送head请求
axios.options(url[, config])发送options请求
axios.post(url[, data[, config]])发送post请求
axios.put(url[, data[, config]])发送put请求
axios.patch(url[, data[, config]])发送patch请求
axios.postForm(url[, data[, config]])使用 multipart/form-data 类型发起 post 请求
axios.putForm(url[, data[, config]])使用 multipart/form-data 类型发起 put 请求
axios.patchForm(url[, data[, config]])使用 multipart/form-data 类型发起 patch 请求
  • 示例代码:

使用axois发送一个普通请求:

// 发起一个 GET 请求 (默认请求方式)
axios('/user/12345');// 发起一个 GET 请求 (默认请求方式)
axios('/user/12345');// 发起一个 GET 请求 (默认请求方式)
axios('/user/12345');

执行GET请求:

// 向给定ID的用户发起请求
axios.get('/user?ID=12345').then(function (response) {// 处理成功情况console.log(response);}).catch(function (error) {// 处理错误情况console.log(error);}).finally(function () {// 总是会执行});

携带参数:

// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {params: {ID: 12345}}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);}).finally(function () {// 总是会执行});  

axios的响应数据如下:

{// `data` 由服务器提供的响应data: {},// `status` 来自服务器响应的 HTTP 状态码status: 200,// `statusText` 来自服务器响应的 HTTP 状态信息statusText: 'OK',// `headers` 是服务器响应头// 所有的 header 名称都是小写,而且可以使用方括号语法访问// 例如: `response.headers['content-type']`headers: {},// `config` 是 `axios` 请求的配置信息config: {},// `request` 是生成此响应的请求// 在node.js中它是最后一个ClientRequest实例 (in redirects),// 在浏览器中则是 XMLHttpRequest 实例request: {}
}

5.2.1 搭建WEB工程

1)pom.xml:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.1.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>

2)entity:

package com.dfbz.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author lscl* @version 1.0* @intro:*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Book {private Integer id;private String name;private String author;
}

3)Controller:

package com.dfbz.controller;import com.dfbz.entity.Book;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;/*** @author lscl* @version 1.0* @intro:*/
@RestController
@RequestMapping("/book")
public class BookController {@PostMapping("/upload")public Map save(MultipartFile pic, HttpServletRequest request) throws Exception{String realPath = "D:/000";// 前端上传的文件名称String fileName = pic.getOriginalFilename();String suffix = fileName.substring(fileName.lastIndexOf("."));String newFileName = System.currentTimeMillis() + suffix;pic.transferTo(new File(realPath + "/" + newFileName));String url = "http://localhost:8080/upload/" + newFileName;return new HashMap(){{put("flag",true);put("message","图片上传成功");put("statusCode","200");put("picUrl",url);}};}@PostMappingpublic Map save(@RequestBody Book book){return new HashMap(){{put("flag",true);put("message","新增成功");put("book", book);put("statusCode","200");}};}@DeleteMapping("{id}")public Map delete(@PathVariable Integer id){return new HashMap(){{put("flag",true);put("message","删除成功");put("id", id);put("statusCode","200");}};}@PutMapping("{id}")public Map update(@PathVariable Integer id,@RequestBody Book book){return new HashMap(){{put("flag",true);put("message","修改成功");put("id", id);put("book", book);put("statusCode","200");}};}@GetMappingpublic Map findAll(){int i=1/0;return new HashMap(){{put("flag",true);put("message","查询成功");put("BookList",Arrays.asList(new Book(1,"《大学》","曾子"),new Book(2,"《庄子》","庄子"),new Book(2,"《道德经》","老子")));put("statusCode","200");}};}
}

5.2.2 使用axios发送请求

demo01.html:

<body>
<div id="box"><button @click="save">save</button><hr><button @click="deleteById('10')">deleteById</button><hr><button @click="update('100')">update</button><hr><button @click="findAll">findAll</button><hr>
</div><script>new Vue({el: "#box",data: {},methods: {save: function () { // saveaxios({url: "/book",method: "post",data: {id: 1,name: "《论语》",author: "孔子"}}).then(function (response) {console.log(response);})},deleteById: function (id) { // deleteByIdaxios("/book/"+id,{method: "delete"}).then(function (response) {console.log(response);})},update: function (id) { // updateaxios.request({url: "/book/"+id,method: "put",data: {id: 2,name: "《孟子》",author: "孟子"}}).then(function (response) {console.log(response);})},findAll: function () { // findAll// 默认发送GET请求axios("/book").then(function (response) {console.log(response);})}}})
</script></body>

demo02.html

<body>
<div id="box"><button @click="save">save</button><hr><button @click="deleteById('10')">deleteById</button><hr><button @click="update('100')">update</button><hr><button @click="findAll">findAll</button><hr>
</div><script>new Vue({el: "#box",data: {},methods: {save() {axios.post("/book", {id: 10, name: "《永乐大典》", author: "解缙"}).then(function (res) {// data是服务端响应的数据console.log(res.data)}).catch(function (err) {console.log(err);});},deleteById(id) {axios.delete("/book/" + id).then(function (res) {console.log(res.data)}).catch(function (err) {console.log(err);});},update(id) {axios.put("/book/" + id, {id: 10, name: "《天工开物》", author: "宋应星"}).then(function (res) {console.log(res.data)}).catch(function (err) {console.log(err);});},findAll() {axios.get("/book").then(function (res) {console.log(res.data)}).catch(function (err) {console.log(err);           // 异常信息});}}})
</script></body>

demo03.html

<body>
<div id="box"><input type="file" id="file"><button @click="upload">上传文件</button></div><script>new Vue({el: "#box",data: {},methods: {upload() {// 构建一个multipart/form-data的请求,用于上传文件axios.postForm("http://localhost:8080/book/upload", // 上传的文件对象,需要用FormData包装一下{pic: document.getElementById("file").files[0]}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);});}}})
</script></body>

5.3 axios配置

我们可以指定axios的默认配置,这些配置将作用于每个axios请求。配置如下:

// 创建一个axios实例
const instance = axios.create({baseURL: 'https://some-domain.com/api/',timeout: 1000,headers: {'X-Custom-Header': 'foobar'}
});//可用的配置项如下:
{// `url` 是用于请求的服务器 URLurl: '/user',// `method` 是创建请求时使用的方法method: 'get', // 默认值// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URLbaseURL: 'https://some-domain.com/api/',// `transformRequest` 允许在向服务器发送前,修改请求数据// 它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法// 数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream// 你可以修改请求头。transformRequest: [function (data, headers) {// 对发送的 data 进行任意转换处理return data;}],// `transformResponse` 在传递给 then/catch 前,允许修改响应数据transformResponse: [function (data) {// 对接收的 data 进行任意转换处理return data;}],// 自定义请求头headers: {'X-Requested-With': 'XMLHttpRequest'},// `params` 是与请求一起发送的 URL 参数// 必须是一个简单对象或 URLSearchParams 对象params: {ID: 12345},// `paramsSerializer`是可选方法,主要用于序列化`params`// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)paramsSerializer: function (params) {return Qs.stringify(params, {arrayFormat: 'brackets'})},// `data` 是作为请求体被发送的数据// 仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法// 在没有设置 `transformRequest` 时,则必须是以下类型之一:// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams// - 浏览器专属: FormData, File, Blob// - Node 专属: Stream, Bufferdata: {firstName: 'Fred'},// 发送请求体数据的可选语法// 请求方式 post// 只有 value 会被发送,key 则不会data: 'Country=Brasil&City=Belo Horizonte',// `timeout` 指定请求超时的毫秒数。// 如果请求时间超过 `timeout` 的值,则请求会被中断timeout: 1000, // 默认值是 `0` (永不超时)// `withCredentials` 表示跨域请求时是否需要使用凭证withCredentials: false, // default// `adapter` 允许自定义处理请求,这使测试更加容易。// 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。adapter: function (config) {/* ... */},// `auth` HTTP Basic Authauth: {username: 'janedoe',password: 's00pers3cret'},// `responseType` 表示浏览器将要响应的数据类型// 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'// 浏览器专属:'blob'responseType: 'json', // 默认值// `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)// 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求// Note: Ignored for `responseType` of 'stream' or client-side requestsresponseEncoding: 'utf8', // 默认值// `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称xsrfCookieName: 'XSRF-TOKEN', // 默认值// `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值// `onUploadProgress` 允许为上传处理进度事件// 浏览器专属onUploadProgress: function (progressEvent) {// 处理原生进度事件},// `onDownloadProgress` 允许为下载处理进度事件// 浏览器专属onDownloadProgress: function (progressEvent) {// 处理原生进度事件},// `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数maxContentLength: 2000,// `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数maxBodyLength: 2000,// `validateStatus` 定义了对于给定的 HTTP状态码是 resolve 还是 reject promise。// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),// 则promise 将会 resolved,否则是 rejected。validateStatus: function (status) {return status >= 200 && status < 300; // 默认值},// `maxRedirects` 定义了在node.js中要遵循的最大重定向数。// 如果设置为0,则不会进行重定向maxRedirects: 5, // 默认值// `socketPath` 定义了在node.js中使用的UNIX套接字。// e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。// 只能指定 `socketPath` 或 `proxy` 。// 若都指定,这使用 `socketPath` 。socketPath: null, // default// `httpAgent` and `httpsAgent` define a custom agent to be used when performing http// and https requests, respectively, in node.js. This allows options to be added like// `keepAlive` that are not enabled by default.httpAgent: new http.Agent({ keepAlive: true }),httpsAgent: new https.Agent({ keepAlive: true }),// `proxy` 定义了代理服务器的主机名,端口和协议。// 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。// 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。// `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。// 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。// 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`proxy: {protocol: 'https',host: '127.0.0.1',port: 9000,auth: {username: 'mikeymike',password: 'rapunz3l'}},// see https://axios-http.com/zh/docs/cancellationcancelToken: new CancelToken(function (cancel) {}),// `decompress` indicates whether or not the response body should be decompressed // automatically. If set to `true` will also remove the 'content-encoding' header // from the responses objects of all decompressed responses// - Node only (XHR cannot turn off decompression)decompress: true // 默认值}

配置axios参数:

// 创建一个axios实例,设置该实例的配置
const instance = axios.create({// 请求地址baseURL: 'http://localhost:8080/',// 请求超时时间timeout: 1000,// 自定义请求头headers: {'X-Custom-Header-Username': 'xiaohui',"X-Custom-Header-Password":"admin"}
});// 设置全局的axios默认配置
axios.defaults.baseURL = 'http://localhost:8080/';
axios.defaults.headers['X-Custom-Header-Username'] = "xiaolan";
axios.defaults.headers['X-Custom-Header-Password'] = "123456";

5.4 axios拦截器

axios 拦截器允许在请求被发送之前或响应被处理之后执行某些操作。拦截器可以用来添加全局的行为,例如在每个请求中自动加入认证信息、处理错误响应、重试失败的请求等。通过使用拦截器,可以将一些通用的操作抽象出来,从而避免在每个请求中重复相同的代码。

请求拦截器:

/*** 添加请求拦截器* config: 请求的配置对象*/
axios.interceptors.request.use(function (config) {// 在发送请求之前做些什么console.log("请求拦截器执行...", config);// 添加自定义的请求头信息config.headers["x-custom-header-username"] = "xiaohui";config.headers["x-custom-header-password"] = "admin";return config;
}, function (error) {// 对请求错误做些什么return Promise.reject(error);
});

响应拦截器:

/*** 添加响应拦截器* response: 响应对象*/
axios.interceptors.response.use(function (response) {// 对响应数据做点什么// 2xx 范围内的状态码都会触发该函数。console.log("响应拦截器执行...", response);response.data.msg = "我是响应拦截器返回的消息";return response;
}, function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么return Promise.reject(error);
});

相关文章:

零基础一篇打通Vue极速通关教程

文章目录 写给零基础看的Vue极速掌握教程第1章 Vue简介1.1 Vue 概述1.2 MVVM 模式1.3 WebStorm开发工具1.3.1 WebStorm简介1.3.2 集成Vue开发调试工具 第2章 Vue的事件绑定2.1 Vue基本使用2.1.1 插值表达式2.1.2 注意事项 2.2 Vue事件绑定2.1.1 点击事件2.2.2 键盘事件2.2.3 移…...

商城系统中的常见 BUG

以下是商城系统中一些常见的 BUG&#xff1a; 功能与操作类 支付问题&#xff1a;如无法成功完成支付&#xff0c;支付过程中出现延迟、错误或订单重复支付等&#xff0c;还可能因网络问题导致支付失败或数据不一致。 登录 / 注册问题&#xff1a;用户在注册或登录时可能遇到…...

下定决心不去读研了。。。

大家好&#xff0c;我是苍何。 之前发表过一篇文章&#xff0c;表达了自己读研的困惑和纠结&#xff0c;得到了大家很多的建议&#xff0c;也引起了很多人的共鸣&#xff0c;在留言区分享了自己的故事&#xff0c;看着这些故事&#xff0c;我觉得都够苍何写一部小说了。 可惜苍…...

100个网络基础知识

1)什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2)OSI 参考模型的层次是什么? 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;会话层&#xff0c;表示…...

庄小焱——2024年博文总结与展望

摘要 大家好&#xff0c;我是庄小焱。岁末回首&#xff0c;2024 年是我在个人成长、博客创作以及生活平衡方面收获颇丰的一年。这一年的经历如同璀璨星辰&#xff0c;照亮了我前行的道路&#xff0c;也为未来的发展奠定了坚实基础。 1. 个人成长与突破 在 2024 年&#xff0c…...

高通8255 Android STR 启动失败要因分析调查

目录 背景&#xff1a; 调查过程&#xff1a; 步骤1&#xff1a; slog2info | grep vmm_service 步骤2&#xff1a; slog2info | grep qvm 总结&#xff1a; 解决方案 背景&#xff1a; 调试高通8255 STR的STR过程中发现Android和QNX进入STR状态后&#xff0c;脱出STR时…...

Qt QML专栏目录结构

第1章 走进Qt Quick的世界... 4 ★1.4 Qt Quick应用... 4 ★1.5 Qt Quick UI项目(qmlproject工程) 4 第2章 QML语法... 4 ★2.2 import导入语句... 4 ★2.3 QML类型系统... 5 ★2.4 对象特性&#xff08;Attributes&#xff09;... 6 三个等于号JavaScript语…...

“深入浅出”系列之FFmpeg:(3)音视频开发的学习路线和必备知识

一、岗位要求 音视频开发属于我自己想要学习的板块&#xff0c;我想知道公司招聘音视频开发工程师所需要的条件&#xff0c;于是我就从招聘网站上找来了几个有关音视频开发的岗位需求&#xff0c;内容仅供参考&#xff1a; &#xff08;1&#xff09;算法工程师-视频编解码 …...

Webpack简述

一、为什么要构建工具 人类喜欢书写的代码以及开发方式计算机不喜欢&#xff0c;构建工具的作用就是让人类舒舒服服写自己喜欢的代码&#xff0c;然后一打包生成计算机喜欢的代码 第一个webpack自身仅仅是将我们引入的模块打包成一个文件&#xff08;编译import&#xff09;&am…...

解决 Error: Invalid or corrupt jarfile day04_studentManager.jar 报错问题

在 Java 开发过程中&#xff0c;我们可能会遇到这样的报错信息&#xff1a;Error: Invalid or corrupt jarfile day04_studentManager.jar。这个错误通常表示 day04_studentManager.jar 文件可能已损坏或无效&#xff0c;下面将为大家详细介绍如何解决这个问题。 一、错误点分…...

ACL基础理论

ACL ——访问控制列表 ACL属于策略的一种 ACL访问控制列表的作用&#xff1a; 访问控制&#xff1a;在路由器流量流入或流出的接口上&#xff0c;匹配流量&#xff0c;然后执行设定好的动作&#xff1a;permit&#xff08;允许&#xff09;、deny&#xff08;拒绝&#xff…...

庄周梦蝶1

和尚大概的意思如下&#xff1a;人的每一个梦境都是一个世界&#xff0c;这些世界统称三千世界。每一个世界当中所谓时间的跨度不同&#xff0c;发展程度不同&#xff0c;但是里面都有一个你。这些世界是同时存在的&#xff0c;所以不存在未来过去和现在&#xff0c;因为你就存…...

使用SIPP发起媒体流性能测试详解

使用SIPP发起媒体流性能测试详解 一、SIPP工具简介二、测试前的准备三、编写测试脚本四、运行测试五、分析测试结果六、总结SIPP(SIP Performance Protocol)是一个开源工具,专门用于SIP(Session Initiation Protocol)协议的性能测试和基准测试。SIP是一种用于控制多媒体通…...

瑞利衰落信道机理的详解

瑞利衰落信道&#xff08;Rayleigh fading channel&#xff09;是一种无线电信号传播环境的统计模型&#xff0c;用于描述信号在无线信道中的传播特性。这种模型假设信号通过无线信道后&#xff0c;其信号幅度是随机的&#xff0c;即“衰落”&#xff0c;并且其包络服从瑞利分布…...

PyTorch使用教程(2)-torch包

1、简介 torch包是PyTorch框架最外层的包&#xff0c;主要是包含了张量的创建和基本操作、随机数生成器、序列化、局部梯度操作的上下文管理器等等&#xff0c;内容很多。我们基础学习的时候&#xff0c;只有关注张量的创建、序列化&#xff0c;随机数、张量的数学数学计算等常…...

Bash语言的函数实现

Bash语言的函数实现 Bash&#xff08;Bourne Again SHell&#xff09;是一种流行的命令行解释器&#xff0c;用于Unix和类Unix操作系统。它不仅支持命令行操作&#xff0c;还能通过脚本语言进行编程。函数是Bash脚本编程中的一个重要概念&#xff0c;可以帮助我们组织代码、提…...

ChatGPT 写作系列

ChatGPT 辅助写作 | 专栏 1 写作核心​ 先讲一下 ChatGPT 写作的核心。核心就是需要有文章大纲&#xff0c;而且文章大纲要足够细致。​ 具体怎么做呢&#xff1f;​ 提前准备多级标题大纲&#xff0c;刚开始有两个级别的标题就行&#xff0c;等用熟练了再细化。分一级标题&…...

RK3576 Android14 状态栏和导航栏增加显示控制功能

问题背景&#xff1a; 因为RK3576 Android14用户需要手动控制状态栏和导航栏显示隐藏控制&#xff0c;包括对锁屏后下拉状态栏的屏蔽&#xff0c;在设置功能里增加此功能的控制&#xff0c;故参考一些博客完成此功能&#xff0c;以下是具体代码路径的修改内容。 解决方案&…...

SDL2:arm64下编译使用 -- SDL2多媒体库使用音频实例

更多内容&#xff1a;XiaoJ的知识星球 SDL2&#xff1a;Android-arm64端编译使用 2. SDL2&#xff1a;Android-arm64端编译使用2.1 安装和配置NDK2.2 下载编译SDL22.3 SDL2使用示例&#xff1a;Audio2.4 Android设备运行 2. SDL2&#xff1a;Android-arm64端编译使用 在Linux系…...

Syncthing在ubuntu下的安装使用

以前安装这个软件的时候&#xff0c; 是在windows和mac上&#xff0c;都是图形化的安装方式&#xff0c;但是ubuntu不太一样&#xff0c;需要增加源&#xff0c;然后执行命令。安装的系统版本是2004。 参考链接1&#xff0c;主要命令包含下面几个部分&#xff1a; 第一步&…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...