【问题标题】:Vue - Pass data from child component from axios reponseVue - 从 axios 响应中传递来自子组件的数据
【发布时间】:2019-06-19 14:54:55
【问题描述】:

我有一个父组件和 2 个子组件。在 ChildComponent1 中,我使用 axios 获取我的数据并使用 v-for ( Cars to rent ) 列出它。每个数据块都有一个按钮,单击该按钮后,它应该选择该车辆。选定的车辆数据应传输到作为预订摘要卡或面板的 ChildComponent2。 链接:

https://codesandbox.io/s/koyjjoo1y3

我不确定在这里采取什么方法。我使用道具将响应数据从父母传递给孩子。但我不知道如何在单击按钮时将数据从 1 个孩子传递给另一个孩子。

Result.vue / Parent

    <section class="section__results--cars">

      <div class="col-lg-8">
         <cars-details></cars-details>
      </div>
      <div class="col-lg-4">
          <booking-summary></booking-summary>
      </div>
    </section>


CarsDetails.vue / Child1

<v-card class="mb-3" v-for="car in cars" :key="car.id">
  <img :src="car.image"></img>
     <h4 class="title">{{ car.title }}</h4>

        <car-attributes
           :maxPersons="car.maxPersons"
           :maxLuggage="car.maxLuggage"
           :interiorColor="car.interiorColor"
           :exteriorColor="car.exteriorColor"
        ></car-attributes>

        <div>
          <span class="price__title">Hourly price</span>
          <span class="price__value">{{ car.pricePerHour }}€</span>
          <v-btn @click="passData">Select Car</v-btn>
        </div>
        <div>
          <h6 class="subheading font-weight-medium">Description</h6>
          <p>{{ car.description }}</p>
        </div>
</v-card>
<script>
    import axios from "axios";
    const URL = "https://next.json-generator.com/api/json/get/NJgWweNm8";
    import CarAttributes from "@/components/cars/CarAttributes";
    export default {
      name: "carsdetails",
      components: { CarAttributes },
      data: () => ({
        cars: []
      }),
      mounted() {
        axios
          .get(URL)
          .then(response => {
            this.cars = response.data;
          })
          .catch(e => {
            this.errors.push(e);
          });
      }
    };
    </script>



BookingSummary.vue / Child2

<v-card>
   <h4>Booking Summary</h4>
   <h6>{{ car.title }}</h6>
   <h6>{{ car.maxPersons}}</h6>
</v-card>

【问题讨论】:

  • 组件间通信需要eventBus。

标签: vuejs2


【解决方案1】:

主要的设计模式是Data -> Down和Events Up。使用$emit('some-event', payload) 将事件向上推送,并使用`@some-event="yourFunction" 来处理它。

这篇文章解释了为什么这种模式有效(并且长期有效):https://jasonformat.com/props-down-events-up/

适合您的用例

Parent

    <template>
      <div>
         <cars-details 
           v-for="(car, i) in cars" 
           :key="i" 
           :car="car" 
           @getCar="getCar" 
         />
      </div>
      <div v-if="selectedCar">
          <booking-summary :car="selectedCar" />
      </div>
    </template>

    <script>
      export default {
        data: {
          cars: [car1, car2, ...],
          selectedCar: null
        },
        methods: {
          getCar(car) {
            this.selectedCar = car
            // Do axios call for the `car` object
          }
        }
      }
    </script>


Child1

    <template>
      ...
      <div>
        ...
        <v-btn @click="passData">Select Car</v-btn>
      </div>
    </template>

    <script>
      export default {
        ...
        props: {
          car: { required: true }
        },
        methods: {
          passData() {
            this.$emit('getCar', this.car)
          }
        }
      }
    </script>


Child2

    <template>
      ...
    </template>

    <script>
      export default {
        ...
        props: {
          car: { required: true }
        },
      }
    </script>

【讨论】:

  • 这两个答案都非常好并且很有帮助。我想知道你和他的答案有什么区别。当它们都工作时,处理发射事件。我对此很陌生,并试图理解。但无论如何谢谢你。这很有帮助。
  • 我还添加了` selectedCar: { title: "Choose a vehicle" }` - 这样“预订摘要”选项卡就不会抛出错误,并且默认可见
【解决方案2】:

您应该使用 $emit 来引发一个事件,然后在其他组件中监听该事件。

【讨论】:

    【解决方案3】:

    您需要使用 vueJs eventBus 与整个项目的组件进行通信。
    它易于使用和声明。

    // EventBus.js 文件

    import Vue from 'vue';
    const EventBus = new Vue();
    export default EventBus;
    

    //CarsDetails.vue 组件(创建事件并通过它传递数据)

    import EventBus from "../../EventBus";
    export default {
      name: "carsdetails",
      data: () => ({
        isClicked: true,
        cars: []
      }),
      methods: {
        ok(car) {
          console.log(car);
          EventBus.$emit("finished", car);
        }
       }
    };
    

    //BookingSummary.vue组件(监听事件)

    import EventBus from "../../EventBus";
    export default {
      name: "bookingsummary",
      data() {
        return {
          car: null
        };
      },
      created() {
        EventBus.$on("finished", x => {
          this.car = x;
        });
        console.log(this.car);
      }
    };
    

    这是更新的代码 https://codesandbox.io/s/n42j172jol

    【讨论】:

    • 非常感谢,您和 Grigios 的回答都很好。我只需要接受一个答案。但两者都有效。我试图理解你的答案之间的区别。非常感谢,
    • $emit 仅在父子组件之间起作用。而 eventBus 用于跨任何 2 个组件进行通信(即它们可能是也可能不是父子组件)。
    • 所以 eventBus 也可以用来在 2 个单独的视图之间进行通信?例如,第一个视图中的输入可以将输入数据发送到第二个视图?不是在谈论具体相关的观点?
    猜你喜欢
    • 2019-08-12
    • 2021-07-19
    • 2019-07-03
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2019-06-08
    • 2018-12-05
    • 2017-10-20
    相关资源
    最近更新 更多