async await,回调函数,箭头函数this指向问题
通过一个获取音乐api接口的例子,分别async函数来写获取歌曲列表方法,回调函数来写播放音乐方法,箭头函数来写播放mv方法。分别来看一下三个函数的this指向问题。接口地址为https://autumnfish.cn
async await例子
async serchMusic()用async修饰serchmusic这个方法。本质就是告诉编译器这是个async到异步处理函数。
通过let response = await axios来取代.then()的回调方法,可以有效避免回调地狱,使得代码看起来更像是同步执行。response去接受get请求的返回值
async serchMusic() {
var that = this;
try{
let response = await axios.get("https://autumnfish.cn/search?keywords=" + this.query)//请求一个在线音乐播放器地址
console.log(this);//结果为window
console.log(that);//结果为window
this.musiclist = response.data.result.songs;
}catch (err){//处理错误或者不存在的请求
console.error(err);
}
},
.then回调函数
then()方法是异步执行就是当.then()前的方法执行完后再执行then()内部的程序这样就避免了。个人理解回调函数的this是指向window,不属于vue实例对象,所以无法来获取vue实例对象data里面的值。因为vue调用的playMusic方法所以第一次this指向vue对象实例。第二次.then()方法中的this因为.then()方法是属于window所以this也指向widow
playMusic :function (musicId) {
var that = this;
console.log(this);//结果为vue实例
console.log(that);//结果为vue实例
axios.get("https://autumnfish.cn/song/url?id=" + musicId)
.then(function (response) {
console.log(response);//异步函数的返回值
console.log(this);//指向window
console.log(that);//指向vue对象实例
console.log(this.query);//未定义
console.log(that.query);//歌曲名
that.musicUrl = response.data.data[0].url;
}, function (err) {
})
},
箭头函数
箭头函数没有自己的this,使用的是上层作用域的this.所以就是指向vue实例可以获取vue对象data里的数据
playMv: function (mvid) {
var that = this;
console.log(this);//结果为vue实例
console.log(that);//结果为vue实例
axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
.then((response)=> {
console.log(response);//异步函数的返回值
console.log(this);//指向vue对象实例
console.log(that);//指向vue对象实例
console.log(this.query);//歌曲名
console.log(that.query);//歌曲名
//console.log(response.data.data.url);
that.mvUrl = response.data.data.url;
})
}
完整代码复制运行就能播放歌曲
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>音乐接口</title>
<script src="js/vue.js"></script>
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css"
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<script src="https://cdn.bootcss.com/axios/0.19.2/axios.min.js"></script>
<style type="text/css">
.global {
background-size: 100% 100%;
width: 100%;
height: 900px;
}
</style>
</head>
<body>
<div id="app">
<div class="global">
<span>
<input type="text" class="form-control" placeholder="请输入歌手" v-model="query" placeholder="输入歌曲名字"
@keyup.enter="serchMusic" >
<button @click="serchMusic" type="button" class="btn btn-success"
>搜索</button>
</span>
<p style="font-size: 30px;color: red;position: absolute;top: 60%;left: 15%;"></p>
<ul style="position: absolute;left: 0%; top: 40% ; color: red;">
<li v-for="item in musiclist" style="list-style:none;"><br>
<button class="btn btn-success" href="#" @click="playMusic(item.id)">播放音乐</button>
{{item.name}}
<button class="btn btn-success" v-if="item.mvid!=0" @click="playMv(item.mvid)">播放mv</button>
</li>
</ul>
<audio
:src="musicUrl"
controls
autoplay
loop
></audio>
<video :src="mvUrl" controls="controls" autoplay="autoplay" >
您的浏览器不支持 video 标签。
</video>
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
query: "",
musiclist: [],
musicUrl: [],
mvUrl: "",
},
methods: {
async serchMusic() {
var that = this;
// console.log(this);//结果为vue实例
// console.log(that);//结果为vue实例
try{
let response = await axios.get("https://autumnfish.cn/search?keywords=" + this.query)//请求一个在线音乐播放器地址
// console.log(this);//结果为vue实例
// console.log(that);//结果为vue实例
this.musiclist = response.data.result.songs;
}catch (err){//处理错误或者不存在的请求
console.error(err);
}
},
playMusic :function (musicId) {
var that = this;
console.log(this);//结果为vue实例
console.log(that);//结果为vue实例
axios.get("https://autumnfish.cn/song/url?id=" + musicId)
.then(function (response) {
console.log(response);//异步函数的返回值
console.log(this);//指向window
console.log(that);//指向vue对象实例
console.log(this.query);//未定义
console.log(that.query);//歌曲名
that.musicUrl = response.data.data[0].url;
}, function (err) {
})
},
playMv: function (mvid) {
var that = this;
console.log(this);//结果为vue实例
console.log(that);//结果为vue实例
axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
.then((response)=> {
console.log(response);//异步函数的返回值
console.log(this);//指向vue对象实例
console.log(that);//指向vue对象实例
console.log(this.query);//歌曲名
console.log(that.query);//歌曲名
//console.log(response.data.data.url);
that.mvUrl = response.data.data.url;
})
}
},
})
</script>
</body>
</html>