代码之家  ›  专栏  ›  技术社区  ›  wonder95

Vuejs-在父查询完成之前运行子组件方法

  •  0
  • wonder95  · 技术社区  · 8 年前

    我正在开发一个基本的POC应用程序,它在前面有一个Solr搜索功能,可以查找产品,然后搜索结果中的链接使用一条路径转到产品详细信息页面。

    指数js公司

    import Vue from 'vue'
    import Router from 'vue-router'
    import Search from '@/components/Search'
    import Product from '@/components/Product'
    
    Vue.use(Router)
    
    export default new Router({
      routes: [
        {
          path: '/search',
          name: 'Search',
          component: Search
        },
        {
          path: '/product_display/:language/:entity_id',
          name: 'product_display',
          component: Product
        },
      ]
    })
    

    产品vue

    <template>
      <section class="hero is-warning">
      <div class="hero-body">
        <div class="container">
          <h1 class="title">
            {{ product.ss_field_content_title }}
          </h1>
        </div>
      </div>
      <section class="section">
        <div class="container">
          <productSlideshow :slideshowNid="product.is_product_slideshow" 
          :language="product.ss_language"></productSlideshow>
        </div>
      </section>
    </section>
    </template>
    
    <script>
    import axios from 'axios'
    import ProductSlideshow from '@/components/ProductSlideshow'
    
    export default {
      name: 'Product',
      components: {
        ProductSlideshow
      },
      data () {
        return {
          product: {}
        }
      },
      created () {
        this.getProduct()
      },
      methods: {
        getProduct: function () {
          const params = new URLSearchParams()
          var entityId = this.$route.params.entity_id
          var language = this.$route.params.language
          params.append('fq', 'bundle:product_display')
          params.append('fq', 'entity_id:' + entityId)
          params.append('fq', 'ss_language:' + language)
          params.append('wt', 'json')
          params.append('rows', 1)
          axios.get('https://my.solrurl.com/solr/indexname/select', {
            params: params
          })
          .then(response => {
            this.product = response.data.response.docs[0]
          })
          .catch(e => {
            this.errors.push(e)
          })
        }
      },
      watch: {
        '$route': 'getProduct'
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    进入此页面效果良好。问题是获取子ProductSlideshow组件的必要参数。

    <template>
      <h1>{{ slideshow.label }}</h1>
    </template>
    
    <script>
    import axios from 'axios'
    
    export default {
      name: 'ProductSlideshow',
      props: {
        slideshowNid: {
          type: Number,
          required: true
        },
        language: {
          type: String,
          required: true
        }
      },
      data () {
        return {
          slideshow: {},
          slides: {}
        }
      },
      created () {
        this.getSlideshow()
      },
      methods: {
        getSlideshow: function () {
          var language = this.language
          // Get slideshow record from Solr.
          const params = new URLSearchParams()
          params.append('fq', 'bundle:slideshow')
          params.append('fq', 'entity_id:' + this.slideshowNid)
          params.append('fq', 'ss_language:' + language)
          params.append('fq', 'entity_type:node')
          params.append('wt', 'json')
          params.append('rows', 1)
          axios.get('https://my.solrurl.com/solr/indexname/select', {
            params: params
          })
          .then(response => {
            this.slideshow = response.data.response.docs[0]
            this.slides = this.slideshow.sm_field_slideshow_home
          })
        }
      },
      watch: {
        '$route': 'getSlideshow'
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    我看到的是,Solr查询没有返回任何数据来显示幻灯片记录,在检查Solr查询时,这是因为 语言 查询中未定义,因此无法返回任何内容。通过使用各种调试器断点,我发现发生的事情是 getSlideshow() 在从返回结果之前调用 getProduct() 在产品组件中。我尝试删除 已创建() 方法,但这并没有什么区别。

    我需要改变什么,以便 getSlideshow() ProductSlideshow组件中的方法在产品组件的查询完成之前不会被调用?

    1 回复  |  直到 8 年前
        1
  •  0
  •   Yevhenii Herasymchuk    8 年前

    您的问题与Vue激发 created 以同步方式挂钩,因此所有子模板都是在API响应到来之前创建和装载的。 解决方案是使用 Conditional Rendering

    在您的 Product.vue 组件创建一些布尔值,如 isProductFetched 并仅在该值为true时渲染子级。

    <template>
      <section class="hero is-warning">
      <div class="hero-body">
        <div class="container">
          <h1 class="title">
            {{ product.ss_field_content_title }}
          </h1>
        </div>
      </div>
      <section class="section">
        <div class="container">
          <productSlideshow 
          v-if="isProductFetched"
          :slideshowNid="product.is_product_slideshow" 
          :language="product.ss_language"></productSlideshow>
        </div>
      </section>
    </section>
    </template>
    
    <script>
    import axios from 'axios'
    import ProductSlideshow from '@/components/ProductSlideshow'
    
    export default {
      name: 'Product',
      components: {
        ProductSlideshow
      },
      data () {
        return {
         isProductFetched: false,
         product: {}
        }
      },
      created () {
        this.getProduct()
      },
      methods: {
        getProduct: function () {
          const params = new URLSearchParams()
          var entityId = this.$route.params.entity_id
          var language = this.$route.params.language
          params.append('fq', 'bundle:product_display')
          params.append('fq', 'entity_id:' + entityId)
          params.append('fq', 'ss_language:' + language)
          params.append('wt', 'json')
          params.append('rows', 1)
          axios.get('https://my.solrurl.com/solr/indexname/select', {
            params: params
          })
          .then(response => {
            this.product = response.data.response.docs[0]
    
            // At this point, the product is fetched
           this.isProductFetched = true
          })
          .catch(e => {
            this.errors.push(e)
          })
        }
      },
      watch: {
        '$route': 'getProduct'
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    </style>
    

    因此,直到该值变为 true. 另外,不要忘记处理错误案例。