Vue-通过axios响应从子组件传递数据

时间:2019-01-25 18:24:56

标签: vuejs2

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

wandbox

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

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>

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您需要使用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

答案 2 :(得分:1)

主要设计模式为数据-> 事件 <-。使用$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>