Version: Next

8. Axios

Axios是新一代的异步请求技术

  • 在页面中发送异步请求,并接受服务器响应数据,在页面中渲染
  • 页面局部更新技术
  • Ajax

Axios支持RESTFul风格

8.1 Axios Demo

中文网址:https://www.kancloud.cn/yunye/axios/234845/

  • 在页面中引入Axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

8.1.1 GET方式请求

axios.get(url?参数);

  • 写一个基本的后端项目,用Mybatis查询数据库,然后以JSON返回到页面上
@RestController
public class UserController {
@Autowired
UserMapper userMapper;
@GetMapping("/user")
@CrossOrigin // 用来支持跨域访问,不加这个页面请求不到这里的路由
public List<User> queryUserList(){
return userMapper.queryUserList();
}
}
  • 页面Axios异步请求访问
    • .then()指定回调函数,其中response对象封装了服务器响应
    • .catch()指定捕获异常,其中error对象封装了错误信息
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.get("http://localhost:8080/user")
.then(function(response) {
console.log(response);
console.log(response.data)
})
.catch(function(error) {
console.log(error);
});
const vue = new Vue({
el: "#app",
data: {},
methods: {
}
})
</script>
</body>
</html>

image-20200509165439205

8.1.2 POST方式请求

  • 后端
    • 使用@RequestBody用JSON接收对象
@PostMapping("/user/save")
@CrossOrigin
public void addUser(@RequestBody User user){
userMapper.addUser(user);
}
  • 前端
    • 传递一个名为Alice Taylor,密码为12345的user对象
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios post</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.post("http://localhost:8080/user/save", {
name: "Alice Taylor",
password: "12345"
})
.then(function(response) {
console.log(response);
console.log(response.data)
})
.catch(function(error) {
console.log(error);
});
const vue = new Vue({
el: "#app",
data: {},
methods: {
}
})
</script>
</body>
</html>
  • 成功接收到user对象并存储到数据库

8.1.3 Axios并发请求

并发请求:将多个请求在同一时刻发送到后端服务器,再集中处理每个请求的响应结果

  • axios.all([方法1,方法2])来并发请求
  • .then(axios.spread(function(响应1, 响应2){}))对响应做汇总处理
  • .all中的方法与.spread中的响应,按位置一一对应
  • 官网demo
function getUserAccount() {
return axios.get('/user/12345');
}
function getUserPermissions() {
return axios.get('/user/12345/permissions');
}
axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
// 两个请求现在都执行完成
}));

并发请求,分别处理响应

并发两个请求/user/user/id

  • 后端
@GetMapping("/user")
@CrossOrigin
public List<User> queryUserList() {
return userMapper.queryUserList();
}
@GetMapping("/user/{id}")
@CrossOrigin
public User queryUserById(@PathVariable("id") int id) {
return userMapper.queryUserById(id);
}
  • 前端
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios post</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUsers() {
return axios.get("http://localhost:8080/user")
.then(function(response) {
console.log(response.data);
});
}
function getUserById(id) {
return axios.get("http://localhost:8080/user/" + id)
.then(function(response) {
console.log(response.data);
});
}
axios.all([getUsers(), getUserById(2)])
const vue = new Vue({
el: "#app",
data: {},
methods: {}
})
</script>
</body>
</html>
  • 服务器响应

image-20200509175007684

并发请求,集中处理响应

  • 使用.then(axios.spread(function(response1, response2...){}))
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>axios post</title>
</head>
<body>
<div id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
function getUsers() {
return axios.get("http://localhost:8080/user");
}
function getUserById(id) {
return axios.get("http://localhost:8080/user/" + id);
}
axios.all([getUsers(), getUserById(2)])
.then(axios.spread(function(response1, response2) { //集中处理响应
console.log(response1.data);
console.log(response2.data);
}));
const vue = new Vue({
el: "#app",
data: {},
methods: {}
})
</script>
</body>
</html>

image-20200509175713730

8.2 Axios与Vue整合案例

查询天气

  • 输入城市名称,返回对应城市天气内容
  • 在搜索框上按回车开始查询,或者点搜索按钮开始查询
  • 后端
@RestController
@RequestMapping("/city")
public class CityController {
@GetMapping("/find")
@CrossOrigin
public Map<String, String> findWeatherByCity(String cityName) {
Map<String, String> map = new HashMap<>();
String cityWeather = getWeatherByCityName(cityName);
map.put("cityName", cityWeather);
return map;
}
public String getWeatherByCityName(String cityName) {
Map<String, String> weathers = new HashMap<>();
weathers.put("北京", "晴天,空气质量良好");
weathers.put("上海", "多云转晴,空气质量优质");
weathers.put("西安", "沙尘暴,空气质量差");
weathers.put("广州", "暴风雨,空气湿度大");
weathers.put("成都", "晴天,气温特别高");
return weathers.get(cityName);
}
}
  • 前端
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Axios Vue 查询天气</title>
</head>
<body>
<div id="app">
<input type="search" v-model="searchContent" @keyup.enter="searchCity" @keyup.delete="hide" /> <input type="button"
value="搜索" @click="searchCity" />
<br>
<span v-for="city in hotCities">
|<a href="#" @click.prevent="searchCityA(city)"> &nbsp;{{city}} &nbsp;|</a>
</span>
<hr>
<span v-show="showFlag"> {{searchContent}},{{weather}}</span>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const vue = new Vue({
el: "#app",
data: {
hotCities: ["北京", "西安", "广州", "上海", "成都"],
searchContent: "",
weather: "",
showFlag: false
},
methods: {
searchCity() {
//获得搜索框内容
console.log(this.searchContent);
//axios异步请求后端
axios.get("http://localhost:8080/city/find?cityName=" + this.searchContent)
.then(function(response) {
//替换页面元素内容
vue.weather = response.data.cityName;
vue.showFlag = true;
})
.catch(function(error) {
console.log(error);
});
},
searchCityA(cityName) {
vue.searchContent = cityName;
vue.searchCity();
},
hide() {
vue.showFlag = false;
}
}
})
</script>
</body>
</html>