VueJs 不显示从 axios 承诺获取的图像,然后将图像 url 放在 src 中
2020-09-24
1394
我正在尝试调用一个 API,一旦我得到响应,我想定位 image_url 属性,但我收到此错误
渲染时出错:“TypeError:无法读取未定义的属性‘image_url’”
和
无法读取 VueComponent.getImages1 (Info.vue?42ed:39) 上未定义的属性‘image_url’
我已经在另一个 Javascript 文件中测试了我的代码,在那里它可以运行,但由于某种原因,在这里却不行。我还检查了父状态是否通过 Vue 控制台正确地将数据发送到子状态,并且它已经起作用了。
Info.vue
<template>
<section>
<img :src="getImages1()" alt="./assets/notFound.png" />
<img :src="getImages2()" alt="./assets/notFound.png" />
</section>
</template>
<script>
import axios from "axios";
export default {
props: {
anime1: String,
anime2: String,
},
methods: {
animeFind(anime) {
axios
.get(`https://api.jikan.moe/v3/search/anime?q=${anime}`)
.then(async function(response) {
const id = await response.data["results"][0]["mal_id"];
await axios
.get(`https://api.jikan.moe/v3/anime/${id}`)
.then(function(response) {
return response.data;
})
.catch(function(error) {
return error; // take care of this later
});
})
.catch(function(error) {
return error; // take care of this later
});
},
// eslint-disable-next-line no-unused-vars
getImages1() {
let response = this.animeFind(this.anime1);
return response["image_url"];
},
getImages2() {
let response = this.animeFind(this.anime2);
return response["image_url"];
},
},
};
</script>
<style></style>
我试过这样做并且它起作用了
main.js
const axios = require("axios");
const animeFind = (anime) =>
axios
.get(`https://api.jikan.moe/v3/search/anime?q=${anime}`)
.then(async function (response) {
const id = await response.data["results"][0]["mal_id"];
await axios
.get(`https://api.jikan.moe/v3/anime/${id}`)
.then(function (response) {
console.log(response.data["image_url"]);
})
.catch(function (error) {
console.log(error);
});
})
.catch(function (error) {
console.log(error);
});
animeFind("Naruto");
animeFind("Cowboy Bebop");
这是父组件,只有当单击按钮时,图像才会改变
<template>
<section class="hero">
<div class="parent-1">
<h1 class="title is-1">Compare two animes! :)</h1>
</div>
<div class="columns">
<div class="column">
<b-field class="label" label="Anime 1">
<b-input value="Enter the first anime!" v-model="anime1"></b-input>
</b-field>
</div>
<div class="column">
<b-field class="label" label="Anime 2">
<b-input value="Enter the second anime!" v-model="anime2"></b-input>
</b-field>
</div>
</div>
<div class="button-spacing">
<b-button class="button" type="is-primary" @click="checkComplete"
>Compare!</b-button
>
</div>
<Info :anime1="anime1" :anime2="anime2" v-if="success">Wow</Info>
</section>
</template>
<script>
import Vue from "vue";
import Buefy from "buefy";
import "buefy/dist/buefy.css";
import Info from "./Info.vue";
Vue.use(Buefy);
export default {
components: {
Info,
},
data() {
return {
anime1: "",
anime2: "",
success: false,
};
},
methods: {
// log() {
// console.log(this.anime1);
// console.log(this.anime2);
// },
checkComplete() {
if (this.anime1.length > 0 && this.anime2.length > 0) {
// let animeData1 = this.animeFind(this.anime1);
// let animeData2 = this.animeFind(this.anime2);
this.success = true;
return this.$buefy.toast.open({
message: "Yay, just a moment now!",
type: "is-success",
position: "is-bottom",
duration: 3000,
});
}
this.success = false;
return this.$buefy.toast.open({
duration: 3000,
message: `Please fill out both fields`,
position: "is-bottom",
type: "is-danger",
});
},
},
};
</script>
2个回答
我认为你对承诺仍然有点困惑。你的 animFind 函数没有返回任何内容。
相反,尝试
<template>
<section>
<img :src="url1" alt="./assets/notFound.png" />
<img :src="url2" alt="./assets/notFound.png" />
</section>
</template>
<script>
import axios from "axios";
export default {
props: {
anime1: String,
anime2: String,
},
data() {
return {
url1: '',
url2: '',
error: ''
}
},
methods: {
animeFind(anime, data) {
axios
.get(`https://api.jikan.moe/v3/search/anime?q=${anime}`)
.then(response => {
const id = response.data["results"][0]["mal_id"];
axios
.get(`https://api.jikan.moe/v3/anime/${id}`)
.then(response => this[data] = response.data["image_url"]);
})
.catch(error => {
this.error = error; // take care of this later
});
}
},
watch: {
anime1: {
immediate: true,
handler(newVal, oldVal) {
this.animeFind(newVal, 'url1');
},
},
anime2: {
immediate: true,
handler(newVal, oldVal) {
this.animeFind(newVal, 'url2');
},
},
},
};
</script>
注意使用 if 箭头函数留在 vue 范围内
Sélim Achour
2020-09-24
getImages()
函数在
animeFind()
返回之前返回。因此
getImages()
将返回未定义。
您可以将
axios
调用放入钩子中,当您返回 response.data 对象时,您可以将其分配给数据对象中的属性。您使用此属性代替模板中的函数,因此组件将具有响应性。
请注意,您应该在 axios 调用中的外部函数上使用常规函数,并在
then()
响应上使用箭头函数来获取正确的
this
。
为简单起见,我只处理一个图像示例,但编辑它并不那么复杂。
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<template>
<section>
<p>Show image here</p>
<img :src="urlResponse['image_url']" alt="./assets/notFound.png">
</section>
</template>
<script>
import axios from "axios";
export default {
data() {
return {
urlResponse: {}
};
},
props: {
anime1: String,
anime2: String
},
created() {
this.animeFind(this.anime1);
},
updated() {
this.animeFind(this.anime1);
},
methods: {
animeFind: function(anime) {
axios
.get(`https://api.jikan.moe/v3/search/anime?q=${anime}`)
.then(async response => {
const id = await response.data["results"][0]["mal_id"];
await axios
.get(`https://api.jikan.moe/v3/anime/${id}`)
.then(response => {
this.urlResponse = Object.assign(
{},
this.urlResponse,
response.data
);
return response.data;
})
.catch(function(error) {
return error; // take care of this later
});
})
.catch(function(error) {
return error; // take care of this later
});
}
}
};
</script>
<style></style>
piir
2020-09-24