【问题标题】:How can I execute a method only once in Vue?如何在 Vue 中只执行一次方法?
【发布时间】:2020-02-04 19:46:25
【问题描述】:

我正在创建一个显示产品的 Web 应用程序(所有产品信息都来自数据库),每个产品都有一个 More Details >> 按钮,单击时会打开一个包含该特定产品信息的模式窗口。 js 文件包含被多次调用的 allRecords() 函数,这使得检查中的网络选项卡变得疯狂。我希望它只被调用一次。我看过这个:How to trigger a vue method only once, not every time,我不确定如何将它应用到我的代码中。

下面是我的代码:

PHP 文件

<div id="myapp">
  {{ allRecords() }}
  <div class="content">
    <div class="nested" v-for="product in products">
      ...
    </div>
    <b-modal id="productModal" v-if="chosenProduct" hide-footer="true" ok-title="Buy Now" size="lg" :title="chosenProduct.Name">
      <div class = "inner-container">
        ...
      </div>
    </b-modal>
  </div>
</div>

JS 文件

var app = new Vue({
  'el': '#myapp',
  data: {
    products: "",
    chosenProduct: null
  },
  methods: {
    allRecords: function(){ \\ This function here is being called multiple times
      axios.get('ajaxfile.php')
        .then(function (response) {
          app.products = response.data;
        })
        .catch(function (error) {
          console.log(error);
        });
    },
    chooseProduct: function (product) {
      app.chosenProduct = product
    }
  }
})

【问题讨论】:

  • 为什么要在模板中执行方法?也许在创建的循环中运行它
  • 您可以在组件的mounted 挂钩中执行ajax 请求,并让回调设置allRecords 属性。然后用{{allRecords}}代替{{allRecords()}}
  • 在vue的文档vuejs.org/v2/api/#created
  • @ConstantinGroß 谢谢!所以我在js文件中添加了mounted: function() { this.allRecords() // Calls the method before page loads }, ,并删除了(),正如你所说,我在这里做错了吗?我得到:function () { [native code] }
  • 你想在&lt;h1&gt;标签中显示什么?

标签: javascript vue.js axios bootstrap-vue


【解决方案1】:

根据我上面的评论: 您可以在组件的挂载钩子中执行 ajax 请求。您的回调已经设置了 products 属性。那么就不需要从模板中调用{{allRecords()}},你可以在你的v-for循环中简单地使用products

这是该方法的演示。为了演示(和娱乐)目的,我将您的 php 替换为 icanhazdadjoke API。

var app = new Vue({
  'el': '#myapp',
  data: {
    products: "loading dad joke...",
    chosenProduct: null
  },
  methods: {
    chooseProduct: function(product) {
      app.chosenProduct = product;
    }
  },
  created: function() {
    axios.get('https://icanhazdadjoke.com/search?term=dogs', {
      headers: {
        Accept: 'application/json'
      }
    })
    .then(function(response) {
      app.products = response.results;
    })
    .catch(function(error) {
      console.log(error);
    });
  }
})
<script src="https://unpkg.com/axios@0.2.1/dist/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="myapp">
  <p v-for="product in products">
    {{product.joke}}
  </p>
</div>

【讨论】:

  • 我建议使用 created 生命周期而不是 mounted 来获取数据,这样您就不必在开始获取数据之前等待 DOM 呈现。
  • 也许是个愚蠢的问题,但{{ products }} 不会打印所有产品信息吗?我已经打印了所有产品信息,我是否遗漏了什么?
  • @AlyssaAlex 在你的情况下,是的。您应该完全删除它,只需将您的divv-for 一起使用
  • 这只是一个示例,因为返回一个字符串用于演示目的。当然,您可以像在标记中那样将产品迭代为数组。
  • 我可以而且应该更清楚,所以我更新了 sn-p 以获取一个数组并使用 v-for 循环遍历它。
猜你喜欢
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 2013-04-06
  • 2021-07-13
相关资源
最近更新 更多