[英]How to have children components have access to parent components method in VueJs
我有一個按鈕,它在我的父組件中執行表單驗證。 如果成功,此按鈕會呈現調用 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>
注意:我已經注釋掉了 axios 請求並始終返回一個圖像 url,以使這個示例在這里工作。
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.