我在父组件中有一个用于执行表单验证的按钮。如果成功,此按钮将呈现一个调用API的子组件。问题是当我更改输入时,显示会同时更改。我试图在父组件中具有animeFind函数,以便我的子组件仅负责UI并知道要显示哪些数据(即有时response.data [“ title”]或response.data [“ image_url”]。
父项
<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"></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: {
checkComplete() {
if (this.anime1.length > 0 && this.anime2.length > 0) {
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>
子组件
<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,
// eslint-disable-next-line no-unused-vars
handler(newVal, oldVal) {
this.animeFind(newVal, "url1");
},
},
anime2: {
immediate: true,
// eslint-disable-next-line no-unused-vars
handler(newVal, oldVal) {
this.animeFind(newVal, "url2");
},
},
},
};
</script>
答案 0 :(得分:0)
注意: 我已注释掉axios请求并返回了图像 网址,始终使该示例在这里工作。
Vue.component('compare-anim', {
template: '#tmpl-compare-anim',
data() {
return {
anime1: "",
anime2: "",
url1: "",
url2: ""
};
},
methods: {
checkComplete() {
if (this.anime1.length > 0 && this.anime2.length > 0) {
this.animeFind(this.anime1, 'url1');
this.animeFind(this.anime2, 'url2');
}
},
animeFind(anime, urlName) {
var responseImg = this.makeRequest(anime);
if (responseImg !== null) {
this[urlName] = responseImg;
}
},
makeRequest(anime) {
//Not gonna make axios request; returning sample image url
//in order to test this implementation
return "https://homepages.cae.wisc.edu/~ece533/images/monarch.png";
/**
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) => (
return response.data["image_url"])
);
})
.catch((error) => {
this.error = error; // take care of this later
return null;
});
**/
}
}
});
Vue.component('render-anim', {
template: '#tmpl-render-anim',
props : {
url1 : {
default: function () {
return "";
}
},
url2 : {
default: function () {
return "";
}
}
},
methods: {
}
});
new Vue({
el: '#app',
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<compare-anim></compare-anim>
</div>
<template id="tmpl-compare-anim">
<section class="hero">
<h1 class="title is-1">Compare two animes! :)</h1>
<input placeholder="Enter the first anime!" v-model="anime1" /><br/><br/>
<input placeholder="Enter the second anime!" v-model="anime2" /><br/><br/>
<button class="button" type="is-primary" @click="checkComplete">Compare!</button>
<render-anim :url1="url1" :url2="url2"></render-anim>
</section>
</template>
<template id="tmpl-render-anim">
<section>
<img :src="url1" v-if="url1" alt="./assets/notFound.png" width="100" />
<img :src="url2" v-if="url1" alt="./assets/notFound.png" width="100" />
</section>
</template>