如何使用第二个组件在两个组件之间共享 ajax 结果?

Posted

技术标签:

【中文标题】如何使用第二个组件在两个组件之间共享 ajax 结果?【英文标题】:How to share ajax results between two components with the first one using the second? 【发布时间】:2018-12-28 22:10:35 【问题描述】:

首先,我是 VueJS 的初学者,所以我可能会向您介绍一堆废话。 :-) 我阅读了所有初学者文档,但我仍然被这个案例所困扰。

我有 2 个由功能组件管理的模板组件:

<template>
  <h2>PageSpeed performance score:  results.score .</h2>
</template>

第二个,使用第一个(第一个需要在其他地方使用才能显示分数:

<template>
  <div>
    <template v-if="results">
      <hosting-performance-score :results="results"/>

      <div
        v-for="(result, rule) in results.rules"
        v-if="result.ruleImpact > 0"
        :key="rule"
        class="panel panel-default"
      >
        <div class="panel-heading"> result.localizedRuleName </div>
        <div class="panel-body">
          <p>
             result.summary.format 

            <b> result.ruleImpact </b>
          </p>
        </div>
      </div>
    </template>
    <i
      v-else
      class="fa fa-spin fa-spinner"
    />
  </div>
</template>

<script>
  import HostingPerformanceScore from './HostingPerformanceScore';

  export default 
    components: 
      HostingPerformanceScore,
    ,
  ;
</script>

然后,具有 AJAX 逻辑的功能性:

<script>
  import axios from 'axios';
  import axiosRetry from 'axios-retry';
  import HostingPerformanceScore from './HostingPerformanceScore';
  import HostingPerformancePage from './HostingPerformancePage';

  axiosRetry(axios);

  export default 
    functional: true,
    props: 
      scoreOnly: 
        default: false,
        type: Boolean,
      ,
      slug: 
        required: true,
        type: String,
      ,
    ,
    data: () => (
      results: null,
    ),
    created() 
      axios.get(Routing.generate('hosting_performance_pagespeed', 
        slug: this.slug,
      )).then((response) => 
        this.results = 
          rules: Object.entries(response.data.formattedResults.ruleResults).map((entry) => 
            const result = entry[1];

            result.ruleName = entry[0];

            return result;
          ).sort((result1, result2) => result1.ruleImpact < result2.ruleImpact),
          score: response.data.ruleGroups.SPEED.score,
        ;
      );
    ,
    render: (createElement, context) => 
      return createElement(
        context.props.scoreOnly ? HostingPerformanceScore : HostingPerformancePage,
        context.data,
        context.children
      );
    ,
  ;
</script>

问题是:我无法访问结果,也不知道如何正确传递:Property or method "results" is not defined on the instance but referenced during render.

或者功能组件可能不是为此而设计的,但我不知道如何以其他方式实现它。你会怎么做?

谢谢! :-)

【问题讨论】:

【参考方案1】:

您似乎有点落后于哪些组件可以正常工作,哪些不能。

由于您的 HostingPerformanceScoreHostingPerformancePage 组件实际上只是渲染数据,它们可以通过仅渲染它们接受的道具来成为功能组件。

您的其他组件必须维护状态,因此它不能是功能组件。

我整理了一个例子来说明这可能是如何工作的。

HostingPerformanceScore

<template functional>
  <h2 v-if="props.results">
    PageSpeed performance score:  props.results.score .
  </h2>
</template>

HostingPerformancePage

<template functional>
  <div>
    <h2>Hosting Performance Page</h2>
    <HostingPerformanceScore :results="props.results"/>
  </div>  
</template>

<script>
import HostingPerformanceScore from "./HostingPerformanceScore.vue";
export default 
  components: 
    HostingPerformanceScore
  
;
</script>

PerformanceResults.vue

<template>
  <HostingPerformanceScore :results="results" v-if="scoreOnly" />
  <HostingPerformancePage :results="results" v-else />
</template>

<script>
import HostingPerformancePage from "./HostingPerformancePage.vue";
import HostingPerformanceScore from "./HostingPerformanceScore.vue";

export default 
  props: 
    scoreOnly: Boolean
  ,
  data() 
    return 
      results: null
    ;
  ,
  created() 
    setTimeout(() => 
      this.results = 
        score: Math.random()
      ;
    , 1000);
  ,
  components: 
    HostingPerformancePage,
    HostingPerformanceScore
  
;
</script>

这是working example。

【讨论】:

确实不错,我试试,谢谢!但它看起来与文档示例相反:vuejs.org/v2/guide/render-function.html#Functional-ComponentsWDYT? @Soullivaneuh 您的意思是您链接的示例使用了渲染功能吗?为了方便起见,我使用了功能模板; Hosting 组件可以很容易地成为渲染函数。函数式组件中的functional并不是通过render函数渲染的,而是没有状态

以上是关于如何使用第二个组件在两个组件之间共享 ajax 结果?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VueJS 中的组件之间共享数据

Angular 2 中兄弟组件之间的数据共享

仅在第一个组件通过验证时有条件地更新第二个组件

如何在Vue中的非父子组件之间共享数据

如何在Vue中的非父子组件之间共享数据

如何在Vue中的非父子组件之间共享数据