首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让子组件访问VueJs中的父组件方法

如何让子组件访问VueJs中的父组件方法
EN

Stack Overflow用户
提问于 2020-09-26 11:16:32
回答 1查看 67关注 0票数 0

我有一个在父组件中执行表单验证的按钮。此按钮如果成功,将呈现一个调用API的子组件。问题是,当我改变输入时,显示同时改变。我正在尝试在父组件中有animeFind函数,这样我的子组件就只负责UI并知道要显示哪些数据(例如,有时是response.data"title“或response.data"image_url”。

父组件

代码语言:javascript
复制
<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>

子组件

代码语言:javascript
复制
<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>
EN

回答 1

Stack Overflow用户

发布于 2020-09-26 12:47:11

注意:我已经注释掉了axios请求,并总是返回一个图像url,以使这个示例在这里工作。

代码语言:javascript
复制
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',
});
代码语言:javascript
复制
<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>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64073513

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档