如何使用 Vue 在 API 端点中自动监视更改?

How to watch for changes automatically in a API Endpoint with Vue?

我正在构建一个使用 Whosebug’s API to get the last question of a certain tag & ouput it on my app. I have been able to get the last question on the specific tag, but now I want that automatically detect changes in the API Endpoint & fetch the last question posted without refreshing the browser or calling the function. I have tried with Computed Properties & Watchers 的应用程序,但我还没有让它运行。我可能做错了或者我的解决方案不是正确的方法。

这是我的代码片段:

<template>
  <div class="question container-fluid">
    <h1 class="my-3"
    >
    Last "<span class="question_tag">{{ tag }}</span>" Question Details
    </h1>
    <b-form
      class="my-4" 
      @submit.prevent="updateTag"
    >
      <b-form-input
        class="w-auto"
        placeholder="Enter a Whosebug tag"
        type="text"
        v-model="newTag"
      >
      </b-form-input>
    </b-form>
    <div class="question_title my-2">
      <strong>Title: </strong> <span>{{ details.title }}</span>
    </div>
    <div class="question_status my-2">
      <strong>Question answered: </strong><span>{{ details.is_answered }}</span>
    </div>
    <div class="question_views my-2">
      <strong>Views: </strong><span>{{ details.view_count }}</span>
    </div>
    <div class="question_answers my-2">
      <strong>Answers Count: </strong><span>{{ details.answer_count }}</span>
    </div>
    <div class="question_link my-2">
      <strong>Check question: </strong>
      <a :href="details.link"
      :title="details.link"
      rel="noopener"
      target="_blank"
      >
        Here
      </a>
    </div>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'QuestionInfo',
  data(){
    return {
      details: '',
      tag: `phaser-framework`,
      newTag: ''
    }
  },
  mounted() {
    this.getTag()
  },
  methods: {
    getTag(){
      axios.get(`https://api.stackexchange.com//2.2/questions?order=desc&sort=creation&tagged=${this.tag}&site=Whosebug`).then(response => {
        this.details = response.data.items[0]
        // console.log an error if get() method is unsuccessful
      }).catch(err => {
        console.log(err)
      })
    },
    updateTag() {
      this.tag = this.newTag
      this.getTag();
    },
  },
}
</script>

编辑:

我想找到客户端解决方案...最好是 Vue 解决方案(如果有的话)。我想尽可能避免使用此功能的服务器端解决方案。

我找到了解决办法。这不是最优雅的,但我最终决定使用 setInterval() 并每隔 10 秒 进行一次 新 API 调用 .每 10 秒 获取新数据不会到达 Stack Exchange API's daily limit 并解决我的问题。

代码段:

<script>
import axios from 'axios'

export default {
  name: 'QuestionInfo',
  data(){
    return {
      details: [],
      tag: `jquery`,
      newTag: ''
    }
  },
  // makes an API call on page load
  mounted() {
    this.getTag()
  },
  methods: {
    getTag(){
      setInterval(() => {
        axios.get(`https://api.stackexchange.com//2.2/questions?order=desc&sort=creation&tagged=${this.tag}&site=Whosebug`).then(response => {
          this.details = response.data.items[0]
        // console.log an error if get() method is unsuccessful
        }).catch(err => {
          console.log(err)
        })
      }, 10000);
    },
    updateTag() {
      this.tag = this.newTag
      this.getTag();
    },
  },
}
</script>

看起来您正在尝试做的是允许服务器向客户端发送事件,而无需客户端请求。有四种方法可以做到这一点。

  1. 定期点击 API。
  2. 长轮询
  3. 服务器发送事件
  4. 网络套接字

第一个是the least efficient and a waste of resources。必须建立每个新的传入连接,必须解析 HTTP headers,必须执行对新数据的查询,并且必须生成并传递响应(通常不提供新数据)。然后必须关闭连接并清理所有资源。

第二种方法是设置 long polling.,其中您仍然通过 HTTP 连接进行连接,但连接会延长,直到收到响应或超时。这样您就不会发送那么多请求。

Server-sent events 将为您解决问题并且是您使用的有效解决方案,但是 mono-directional(从服务器到客户端的通信)因此如果您需要进行通信与 API 一起使用,那么您可能想尝试其他方法。这取决于您的需求。

通常我会推荐 websockets,但这取决于 Whosebug API 是否支持使用 websockets,目前似乎不支持。

对于您的用例,我会首先查看对 websockets 的支持。如果这不起作用,请查看服务器发送的事件是否会为您完成这项工作。如果这还不够,我建议实施 long-polling,这应该有助于减少一些资源浪费。