【问题标题】:Axios response happening after component is rendered组件渲染后发生的axios响应
【发布时间】:2017-10-23 15:39:13
【问题描述】:

我有一个父组件使用 Axios 发出 Ajax 请求,然后将响应分配给一个名为“carousel”的变量,然后向下传递给子组件。

在“created()”的子组件中,我将传递的道具“carousel”分配给一个名为“slides”的新变量

问题是当我这样做时返回未定义,我的想法是 Axios 查询在此发生之前没有返回。

有没有办法在prop传递之前延迟axios请求,子组件总能得到预期的响应。

我的代码如下。

家长

<template>
  <div class='product-container'>
    <home-carousel :carousel="carousel"></home-carousel>
    <profiler></profiler>
    <cta-sections :panels="panels"></cta-sections>
  </div>
</template>

<script>
  import api from '../api/Home'
  import CtaSections from '../components/CtaSections'
  import HomeCarousel from '../components/HomeCarousel'
  import Profiler from '../components/Profiler'
  export default {
    components: {
      CtaSections,
      HomeCarousel,
      Profiler,
    },
    data() {
      return {
        panels: [],
        slides: 'test',
        carouselPass: [],
        carousel: [],
      }
    },
    created() {
      axios.get(window.SETTINGS.API_BASE_PATH + 'pages/5')
        .then(response => {
          this.panels = response.data.acf.split_panels;
          this.carousel = response.data.acf.carousel;
          this.carousel.forEach(function (item, index) {
            if (index === 0) {
              item.active = true;
              item.opacity = 1;
            } else {
              item.active = false;
              item.opacity = 0;
            }
            item.id = index
          })
        })
    },
  }
</script>

儿童

<template>
  <div class='slider'>
    <transition-group class='carouse carousel--fullHeight carousel--gradient' tag="div" name="fade">

      <div v-for="slide in slides" 
      class="carousel__slide" 
      v-bind:class="{ active: slide.active }" 
      :key="slide.id"
      :style="{ 'background-image': 'url(' + slide.image.url + ')' }"
      v-show="slide.active"
      >

        <div class="carousel__caption carousel__caption--centered">
          <h2 class="heading heading--white heading--uppercase heading--fixed">{{ slide.tagline }}</h2>
        </div>
      </div>
    </transition-group>

    <div class='carousel__controls carousel__controls--numbered carousel__controls--white carousel__controls--bottomRight carousel__controls--flex'>
      <div @click="next" class="in">
        <img src="/static/img/svg/next-arrow.svg" />
        <span v-if="carousel.length < 10">0</span>
        <span>{{ slideCount }}</span>
        <span>/</span>
        <span v-if="carousel.length < 10">0</span>
        <span>{{ carousel.length }}</span>
      </div>
    </div>

  </div>
</template>

<script>
import bus from '../bus'
  import Booking from './Booking'
  export default {
    name: 'HomeCarousel',
    props: ['carousel'],
    data() {
      return {
        slideCount: 1,
        slides: [],
        /*
        slides: [{
            image: this.themepath + 'home-banner.jpg',
            active: true,
            captionText: 'A PLACE AS UNIQUE AS YOU ARE',
            buttonText: 'book now',
            buttonUrl: '#',
            opacity: 1,
            id: 1
          },
          {
            image: this.themepath + 'home-banner2.jpg',
            active: false,
            captionText: 'A PLACE AS UNIQUE AS YOU ARE',
            buttonText: 'book now',
            buttonUrl: '#',
            opacity: 0,
            id: 2
          }
        ]
        */
      }
    },

    methods: {
      showBooking: function() {
        this.$store.state.showBooking = true;
      },
      next() {
        const first = this.slides.shift();
        this.slides = this.slides.concat(first)
        first.active = false;
        this.slides[0].active = true;
        if (this.slideCount === this.slides.length) {
          this.slideCount = 1;
        } else {
          this.slideCount++;
        }
      },
      previous() {
        const last = this.slides.pop()
        this.slides = [last].concat(this.slides)

        // Loop through Array and set all active values to false;
        var slideLength = this.slides.length;
        for (var slide = 0; slide < slideLength; slide++) {
          this.slides[slide].active = false;
        }
        // Apply active class to first slide
        this.slides[0].active = true;
        this.slideCount--;
      },
      loopInterval() {
        let self = this;
        setInterval(function () {
          self.next()
        }, 8000);
      }
    },
    created() {
      this.slides = this.carousel;
    }
  }

</script>

【问题讨论】:

    标签: vue.js components axios


    【解决方案1】:

    您可以只观察 prop 并在其更改时设置 this.slides,即异步调用完成时:

    watch:{
      carousel(value) {
        this.slides = value
      }
    }
    

    这是一个 JSFiddle:https://jsfiddle.net/nwLh0d4w/

    【讨论】:

    • 您能不能说得更具体一些?我在哪里看父母或孩子?你有例子吗?
    • 您将其添加到您的孩子,请参阅:vuejs.org/v2/guide/computed.html#Watchers
    • 看过了。不过还是遇到了同样的问题。 Carousel 仍未定义。
    猜你喜欢
    • 2020-03-25
    • 2018-03-24
    • 2019-10-30
    • 2022-01-26
    • 2022-08-18
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-09-11
    相关资源
    最近更新 更多