一、 发送AJAX请求
vue本身不支持发送AJAX请求,需要使用vue-resource、axios等插件实现。
axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对vue-resource进行更新和维护。
二、 使用axios发送AJAX请求
1、 安装axios模块或者下载axios.min.js文件并引入
2、使用方法
2.1 axios([options])
axios({
method:'get',
url:'user.json'
}).then(function(resp){
console.log(resp.data);
}).catch(resp => {
// console.log(resp);
console.log('请求失败:'+resp.status+','+resp.statusText);
});
除了这种公用的方式,作者对于get、post等常用的方法也做了简化(如下)。
2.2 axios.get(url[,options]);
传参数方式:
a、通过url传参
b、通过params选项传参
实例如下:
url传参
axios.get('server.php?name=tom&age=23')
params选项传参
axios.get('server.php',{
params:{
name:'alice',
age:19
}
}).then(resp => {
console.log(resp.data);
}).catch(err => {
console.log('请求失败:'+err.status+','+err.statusText);
});
2.3 axios.post(url,data,[options])
axios默认发送数据时,数据格式是Request Payload,并非我们常用的Form Data格式,所以参数必须要以键值对形式传递,不能以json形式传参。
传参方式:
a、自己拼接为键值对
b、使用transformRequest,在请求发送前将请求数据进行转换
c、如果使用模块化开发,可以使用qs模块进行转换
自己拼接为键值对
axios.post('server.php','name=alice&age=20&')
使用transformRequest,在请求发送前将请求数据进行转换
axios.post('server.php',this.user,{
transformRequest:[
function(data){
let params='';
for(let index in data){
params+=index+'='+data[index]+'&';
}
return params;
}
]
}).then(resp => {
console.log(resp.data);
}).catch(err => {
console.log('请求失败:'+err.status+','+err.statusText);
});
备注:axios本身并不支持发送跨域的请求,没有提供相应的API,作者也暂没计划在axios添加支持发送跨域请求,所以只能使用第三方库。
三、使用vue-resource发送跨域请求
1、 安装vue-resource模块或者下载vue-resource.min.js文件并引入
2、使用方法:
使用this.$http发送请求
this.$http.get(url, [options])
this.$http.head(url, [options])
this.$http.delete(url, [options])
this.$http.jsonp(url, [options])
this.$http.post(url, [body], [options])
this.$http.put(url, [body], [options])
this.$http.patch(url, [body], [options])
下边实例中会演示如何跨域。
四、实战练习
1、向360搜索发送JSONP请求
this.$http.jsonp('https://sug.so.360.cn/suggest',{
params:{
word:'a'
}
}).then(resp => {
console.log(resp.data.s);
});
360完整请求的链接为https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=a
我们可以看到搜索的请求地址为问号前边的https://sug.so.360.cn/suggest,回调函数和jsonp默认的参数一致为callback,所以不用修改,只需要传入关键字(world参数)即可。
2、向百度搜索发送JSONP请求
this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{
params:{
wd:'a'
},
jsonp:'cb' //百度使用的jsonp参数名为cb,所以需要修改
}).then(resp => {
console.log(resp.data.s);
});
百度完整请求的链接为 https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&json=1&p=3&sid=1420_21118_17001_21931_23632_22072&req=2&csor=1&cb=jQuery110208075694879886905_1498805938134&_=1498805938138
我们可以看到百度搜索的请求地址为问号前边的https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su,但是回调函数有些变化(经过尝试确定为cb参数),与jsonp的默认参数不一致,这时候就需要在jsop的参数中修改回调指向(jsonp:'cb'),关键字依然在param对象中的wd参数上指定。
五、完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送AJAX请求</title>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script src="js/vue-resource.min.js"></script>
<script>
window.οnlοad=function(){
new Vue({
el:'#itany',
data:{
user:{
// name:'alice',
// age:19
},
uid:''
},
methods:{
send(){
axios({
method:'get',
url:'user.jsonaaa'
}).then(function(resp){
console.log(resp.data);
}).catch(resp => {
// console.log(resp);
console.log('请求失败:'+resp.status+','+resp.statusText);
});
},
sendGet(){
// axios.get('server.php?name=tom&age=23')
axios.get('server.php',{
params:{
name:'alice',
age:19
}
})
.then(resp => {
console.log(resp.data);
}).catch(err => {
console.log('请求失败:'+err.status+','+err.statusText);
});
},
sendPost(){
// axios.post('server.php',{
// name:'alice',
// age:19
// })
// axios.post('server.php','name=alice&age=20&') //方式1
axios.post('server.php',this.user,{
transformRequest:[
function(data){
let params='';
for(let index in data){
params+=index+'='+data[index]+'&';
}
return params;
}
]
})
.then(resp => {
console.log(resp.data);
}).catch(err => {
console.log('请求失败:'+err.status+','+err.statusText);
});
},
getUserById(uid){
axios.get(`https://api.github.com/users/${uid}`)
.then(resp => {
// console.log(resp.data);
this.user=resp.data;
});
},
sendJSONP(){
//https://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word&word=a
this.$http.jsonp('https://sug.so.360.cn/suggest',{
params:{
word:'a'
}
}).then(resp => {
console.log(resp.data.s);
});
},
sendJSONP2(){
//https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=a&json=1&p=3&sid=1420_21118_17001_21931_23632_22072&req=2&csor=1&cb=jQuery110208075694879886905_1498805938134&_=1498805938138
this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{
params:{
wd:'a'
},
jsonp:'cb' //百度使用的jsonp参数名为cb,所以需要修改
}).then(resp => {
console.log(resp.data.s);
});
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<button @click="send">发送AJAX请求</button>
<button @click="sendGet">GET方式发送AJAX请求</button>
<button @click="sendPost">POST方式发送AJAX请求</button>
<hr>
<br>
GitHub ID: <input type="text" v-model="uid">
<button @click="getUserById(uid)">获取指定GitHub账户信息并显示</button>
<br>
姓名:{
{user.name}} <br>
头像:<img :src="user.avatar_url" alt="">
<hr>
<button @click="sendJSONP">向360搜索发送JSONP请求</button>
<button @click="sendJSONP2">向百度搜索发送JSONP请求</button>
</div>
</body>
</html>
六、模仿百度搜索实例
实现功能:
1、按上下箭头可以在搜索列表中切换当前选中条目,并且将选中条目显示到搜索框中
2、处理切换到列表首位的临界情况
3、没有搜索到数据时,列表不显示,显示‘暂无数据‘字样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送AJAX请求</title>
<style>
.current{
background-color:#ccc;
}
</style>
<script src="js/vue.js"></script>
<script src="js/vue-resource.min.js"></script>
<script>
window.οnlοad=function(){
new Vue({
el:'#itany',
data:{
keyword:'',
myData:[],
now:-1 //当前选中项的索引
},
methods:{
getData(e){
//如果按方向键上、下,则不发请求
if(e.keyCode==38||e.keyCode==40)
return;
this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{
params:{
wd:this.keyword
},
jsonp:'cb'
}).then(resp => {
this.myData=resp.data.s;
});
},
changeDown(){
this.now++;
this.keyword=this.myData[this.now];
if(this.now==this.myData.length){
this.now=-1;
}
},
changeUp(){
this.now--;
this.keyword=this.myData[this.now];
if(this.now==-2){
this.now=this.myData.length-1;
}
}
}
});
}
</script>
</head>
<body>
<div id="itany">
<input type="text" v-model="keyword" @keyup="getData($event)" @keydown.down="changeDown" @keydown.up.prevent="changeUp">
<ul>
<li v-for="(value,index) in myData" :class="{current:index==now}">
{
{value}}
</li>
</ul>
<p v-show="myData.length==0">暂无数据....</p>
</div>
</body>
</html>