Axios
什么是Axios
Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信 ,简单的讲Axios 是一个基于 promise 的 HTTP 库,就是可以发送get、post请求。说到get、post,我们原来都用Jquery。但是由于Vue、React等框架的出现,Jquery也不是那么符合现在的需求了。也正是Vue、React等框架的出现,促使了Axios轻量级库的出现,因为Vue等,不需要操作Dom,所以不需要引入Jquery.js了。
Axios和ajax 的区别
axios是通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样。
简单来说: ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装。axios是ajax,ajax不止axios。我的理Axios解就是升级版ajax 更加匹配现在的Vue等框架
其功能特点如下:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API [ JS中链式编程 ]
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF(跨站请求伪造)
为什么要使用 Axios
由于 Vue.js
是一个 视图层框架 并且作者(尤雨溪)严格准守 SoC (关注度分离原则),所以Vue.js
并不包含 AJAX 的通信功能,为了解决通信问题,作者单独开发了一个名为 vue-resource
的插件,不过在进入 2.0 版本以后停止了对该插件的维护并推荐了 Axios
框架。少用jQuery
,因为它操作Dom太频繁。
第一个 Axios 应用程序
我们在开发中接口大多都是采用json格式,所以我们在这里模拟一段json数据,名为 data.json 的文件并写入以下内容,放在项目的根目录下:
{
"name": "Acoffee",
"url": "https://www.baidu.com",
"page": 1,
"address": {
"street": "武侯区",
"city": "成都市",
"country": "中国"
}
}
代码实现;
<!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">
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<!-- v-cloak 解决闪烁问题-->
<div id="app">
<div>名称:{{info.name}}</div>
<div>
地址:{{info.address.country}}--{{info.address.city}}--{{info.address.street}}
</div>
<div>
链接:<a :href="info.url" target="_blank">{{info.url}}</a>
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data() {
return {
info: { //这里只是规定接收的格式
name: null,
address: {
country: null,
city: null,
street: null
},
url: null
}
}
},
mounted() { //钩子函数
axios.get('data.json').then(response => (this.info = response.data));
}
});
</script>
</body>
</html>
执行结果:
我们可以使用v-cloak 解决问题,它会直接显示全白页面,但是也比直接显示这种无用信息好。
开发中使用场景
this.$axios
.post("/api/queryAllByPage", this.formInline)
.then((res) => {
this.listData = res.data.data.list;
console.log(res);
this.pageparm.total = res.data.data.total;
})
.catch((err) => {
console.log(err);
});
计算属性
什么是计算属性:
计算属性指的是通过一系列运算之后,最终得到一个属性值。定义的时候是方法格式,但是使用的时候当属性使用。这个动态计算出来的属性值可以被模板结构或methods方法使用。
示例代码如下:
<template>
<div>
{{nochange}}
</div>
</template>
<script>
export default {
data() {
return {
message: new Date()
}
},
computed: {
//nochange:计算属性。如果在计算属性的方法中,使用了data中的数据属性(this.message),如果data数据属性(this.message)发生变化 计算属性就会重重新计算
nochange:function () {
return new Date(this.message);
}
},
//生命周期函数
created() {
var that = this;
setInterval(function () {
that.message = new Date();
})
}
}
</script>
实现一个时间走动的效果
虽然我们使用methods也可以实现但是在有些时候methods就会显得冗余,比如下面
我们模拟一个简单的购物车
我们没用计算属性之前,虽然也可以实现但是先得很冗余
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<title>Title</title>
<style>
table {
width: 80%;
border-collapse: collapse;
margin: 100px
}
table td {
border: 1px solid #eee;
padding: 10px
}
</style>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<td>id</td>
<td>名称</td>
<td>价格</td>
<td>数量</td>
<td>小计</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr v-for="(product,index) in productList">
<td>{{product.id}}</td>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>{{product.num}}</td>
<td>{{product.num * product.price}}</td>
<td>
<button @click="addnum(index)">+</button>
<button @click="minsnum(index)">-</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="10">总计:{{totalPrice}}</td>
</tr>
</tfoot>
</table>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
totalPrice: 0,
productList: []
},
computed: {},
created() {
this.productList = [
{id: 1, price: 1, num: 1, name: "手机1"},
{id: 2, price: 3, num: 2, name: "手机2"},
{id: 3, price: 5, num: 3, name: "手机3"},
{id: 4, price: 7, num: 4, name: "手机4"},
{id: 5, price: 9, num: 5, name: "手机5"},
];
//初始化总计
this.totalmoney();
},
methods:{
totalmoney: function(){
var total = 0;
for (var i = 0; i < this.productList.length; i++) {
var product = this.productList[i];
total += (product.price * product.num);
}
//总计
this.totalPrice = total;
},
//减少
minsnum: function (index) {
this.productList[index].num--;
//每次变化都调用总计方法
this.totalmoney();
},
//增加
addnum: function (index) {
this.productList[index].num++;
this.totalmoney();
}
}
})
</script>
</body>
</html>
使用计算属性之后
当我们使用计算属性过后,我们就不需要在每次调用加减方法的时候再去调用计算总计的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<title>Title</title>
<style>
table {
width: 80%;
border-collapse: collapse;
margin: 100px
}
table td {
border: 1px solid #eee;
padding: 10px
}
</style>
</head>
<body>
<div id="app">
<table>
<thead>
<tr>
<td>id</td>
<td>名称</td>
<td>价格</td>
<td>数量</td>
<td>小计</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr v-for="(product,index) in productList">
<td>{{product.id}}</td>
<td>{{product.name}}</td>
<td>{{product.price}}</td>
<td>{{product.num}}</td>
<td>{{product.num * product.price}}</td>
<td>
<button @click="addnum(index)">+</button>
<button @click="minsnum(index)">-</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="10">总计:{{totalPrice}}</td>
</tr>
</tfoot>
</table>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
productList: []
},
computed: {
//totalPrice 计算属性。如果在计算属性的方法中,使用了data中的数据属性(this.productList),
// 如果data数据属性(this.productList)发生变化 计算属性就会重重新计算
totalPrice: function () {
var total = 0;
for (var i = 0; i < this.productList.length; i++) {
var product = this.productList[i];
total += (product.price * product.num);
}
//总计
return total;
}
},
created() {
this.productList = [
{id: 1, price: 1, num: 1, name: "手机1"},
{id: 2, price: 3, num: 2, name: "手机2"},
{id: 3, price: 5, num: 3, name: "手机3"},
{id: 4, price: 7, num: 4, name: "手机4"},
{id: 5, price: 9, num: 5, name: "手机5"},
];
},
//我们在这里增加或者减少就会改变我们的productList,一旦发生了改变computed
//就监听到了改变就会重绘我们的逻辑
methods: {
//减少
minsnum: function (index) {
this.productList[index].num--;
},
//增加
addnum: function (index) {
this.productList[index].num++;
}
}
})
</script>
</body>
</html>
计算数学vs方法
相对于方法来说,计算属性会缓存计算的结果,只有计算属性的依赖项发生变化时,才会重新进行运算。因此计算属性的性能更好:
<body>
<div id="app">
<!--<p>{{count}}乘以2的值为:{{methodsplus()}}</p>-->
<!--<p>{{count}}乘以2的值为:{{methodsplus()}}</p>-->
<!--<p>{{count}}乘以2的值为:{{methodsplus()}}</p>-->
<p>{{count}}乘以2的值为:{{computedplus}}</p>
<p>{{count}}乘以2的值为:{{computedplus}}</p>
<p>{{count}}乘以2的值为:{{computedplus}}</p>
</div>
<script>
var vm = new Vue({
el: "#app",
data() {
return {
count: 1
}
},
computed: {
computedplus() {//计算结果会被缓存,性能好
console.log("计算属性被执行")
return this.count * 2;
}
},
methods: {
methodsplus() {
console.log("方法被执行")
return this.count * 2;
}
}
})
</script>
</body>
方法的执行结果
计算属性的结果
我们可以发现计算属性只执行了一次 这就是因为计算属性缓存了以前的数据项 发现数据想没有改变就没有执行剩下的两次,这就是他的缓存功能
侦听器
1.什么是watch 侦听器
watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。
<body>
<div id="app">
<input type="text" v-model="username">
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
username: ""
},
//所有的侦听器,都应该被定义到watch下面
watch: {
//侦听器本质上是一个函数,要监听那个数据的变化
//就把数据名作为方法名即可
username(newVal,oldVue){
console.log("新值:",newVal,"旧值:",oldVue)
}
}
})
</script>
</body>
依次输入12345观察控制台打印结果
可以用来判断用户名是否被占用
计算属性VS监听器
计算属性和侦听器侧重的应用场景不同:
计算属性侧重于监听多个值的变化,侧重点是最终计算并返回一个新值
侦听器侧重于监听单个数据的变化,最终执行特定的业务处理(侧重点是完成这些特定的业务),不需要有任何返回值