#javascript #html #vue.js #vuejs2
#javascript #HTML #vue.js #vuejs2
Вопрос:
У меня есть кнопка, которая выполняет проверку формы, которая находится в моем родительском компоненте. Эта кнопка в случае успеха отображает дочерний компонент, который вызывает API. Проблема в том, что когда я меняю ввод, отображение меняется одновременно. Я пытаюсь использовать функцию animeFind в родительском компоненте, чтобы мой дочерний компонент просто заботился о пользовательском интерфейсе и знал, какие данные отображать (т.Е. Иногда 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 amp;amp; 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>
Комментарии:
1. Чтобы было понятно. Вы хотите перейти
animeFind
к родительскому компоненту иcheckComplete
функции whenreturns true
; вам нужно вызватьanimeFind
и отправить запрос с помощью axios, ЕСЛИ axios выдает успешный ответ, вам нужно передатьresponse.data
дочерней функции и выполнить рендеринг. Я прав?2. Это правильно
Ответ №1:
Примечание: я закомментировал запрос axios и всегда возвращал URL-адрес изображения, чтобы этот пример работал здесь.
Vue.component('compare-anim', {
template: '#tmpl-compare-anim',
data() {
return {
anime1: "",
anime2: "",
url1: "",
url2: ""
};
},
methods: {
checkComplete() {
if (this.anime1.length > 0 amp;amp; 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>
Комментарии:
1. Что делает идентификатор шаблона, гарантирует ли он, что переменные, объявленные в компоненте vue, доступны с любыми тегами, которые есть в шаблоне?
2. Нет. идентификатор шаблона предназначен для определения, какой шаблон принадлежит какому компоненту. вам не нужно добавлять их в свой код. это не имеет никакого отношения к каким-либо переменным компонентов
3. Есть ли способ модулировать этот код, потому что, если я начну добавлять больше компонентов vue, он станет действительно большим, как у меня будут render-anim и compare-anim в разных файлах? Или вы бы не рекомендовали мне делать это
4. вы можете добавлять их в разные файлы. это не влияет на реализацию. Я добавил это в тот же файл, потому что у меня не может быть здесь нескольких файлов, и я хотел создать фрагмент кода, пригодный для выполнения. Дайте мне знать, если у вас возникнут какие-либо проблемы
5. Я получаю сообщение об ошибке, в котором говорится
TypeError: Cannot read property 'functional' of undefined