Service 什么';VueJS中的角度服务等效于什么?

Service 什么';VueJS中的角度服务等效于什么?,service,vue.js,vuejs2,Service,Vue.js,Vuejs2,我想将所有与服务器通信并获取数据的函数放在VueJS中的一个可重用文件中 插件似乎不是最好的选择。无模板组件..?我使用HTTP客户端进行api调用,我在src文件夹中创建了一个gateways文件夹,并为每个后端放置了文件,创建如下所示 myApi.js import axios from 'axios' export default axios.create({ baseURL: 'http://localhost:3000/api/v1', timeout: 5000, hea

我想将所有与服务器通信并获取数据的函数放在VueJS中的一个可重用文件中

插件似乎不是最好的选择。无模板组件..?

我使用HTTP客户端进行api调用,我在
src
文件夹中创建了一个
gateways
文件夹,并为每个后端放置了文件,创建如下所示

myApi.js

import axios from 'axios'
export default axios.create({
  baseURL: 'http://localhost:3000/api/v1',
  timeout: 5000,
  headers: {
    'X-Auth-Token': 'f2b6637ddf355a476918940289c0be016a4fe99e3b69c83d',
    'Content-Type': 'application/json'
  }
})
现在,在您的组件中,您可以使用一个函数从api中获取数据,如下所示:

methods: {
 getProducts () {
     myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
  }
}
import api from '@/src/utils/api'

Vue.$api = api

Object.defineProperty(Vue.prototype, '$api', {
  get () {
    return api
  }
})

我假设您希望在多个组件中重复使用此方法,您可以使用vue.js:

mixin是为Vue组件分发可重用功能的一种灵活方式。mixin对象可以包含任何组件选项。当组件使用mixin时,mixin中的所有选项都将“混合”到组件自己的选项中

因此,您可以在mixin中添加一个方法,它将在mixin将被混合的所有组件中可用。请参见以下示例:

// define a mixin object
var myMixin = {
  methods: {
     getProducts () {
         myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
      }
  }
}

// define a component that uses this mixin
var Component = Vue.extend({
  mixins: [myMixin]
})

// alternate way to have a mixin while initialising
new Vue({
  mixins: [myMixin],
  created: function () {
    console.log('other code')
  }
})

总共有4种方式:

  • 无状态服务:那么您应该使用mixin
  • 有状态服务:使用Vuex
  • 导出服务并从vue代码导入
  • 任何javascript全局对象

我主要使用Vue资源

1.我使用
Vue.http.xxx
创建了一个新文件,在这里我使用
Vue.http.xxx
连接到API端点。假设我们有一个输出帖子的端点。在项目中创建一个新目录,我称之为
services
,然后创建一个名为
PostsService.js
的文件-内容如下所示:

import Vue from 'vue'

export default {
  get() {
    return Vue.http.get('/api/posts)
  }
}
然后我转到我想要使用这个服务的组件,并导入它

import PostsService from '../services/PostsService'

export default {
  data() {
   return {
     items: []
   }
  },
  created() {
   this.fetchPosts()
  },
  methods: {
   fetchPosts() {
    return PostsService.get()
      .then(response => {
        this.items = response.data
      })
   }
  }
}

有关此方法的更多信息,请随时查看GitHub上的我的repo。我想对于您的简单问题,答案可能是任何包含函数(相当于ANgular中类中的方法)的ES6模块,并使用ES6导入和导出将它们直接导入组件中。没有这样的服务可以注入组件中。

我建议创建一个API提供者,您可以从应用程序中的任何位置访问它

只需创建一个
src/utils
文件夹,并在其中创建一个名为
api.js
的文件

在其中,导出知道如何作为对象或ES6静态类与API通信的包装器(如果您不害怕类,我更喜欢后者的外观和工作方式)。此提供程序可以使用您喜欢的任何HTTP请求库,并且您可以通过更改单个文件(此文件)而不是查找整个代码库来轻松地交换它。下面是一个使用axios的示例,假设我们在
API.example.com/v1
上有一个使用SSL的REST API:

import axios from 'axios'

import { isProduction, env } from '@/utils/env'

const http = null // not possible to create a private property in JavaScript, so we move it outside of the class, so that it's only accessible within this module

class APIProvider {
  constructor ({ url }) {
    http = axios.create({
      baseURL: url,
       headers: { 'Content-Type': 'application/json' }
    })
  }

  login (token) {
    http.defaults.headers.common.Authorization = `Bearer ${token}`
  }

  logout () {
    http.defaults.headers.common.Authorization = ''
  }

  // REST Methods
  find ({ resource, query }) {
    return http.get(resource, {
      params: query
    })
  }

  get ({ resource, id, query }) {
    return http.get(`${resource}/${id}`, {
      params: query
    })
  }

  create ({ resource, data, query }) {
    return http.post(resource, data, {
      params: query
    })
  }

  update ({ resource, id, data, query }) {
    return http.patch(`${resource}/${id}`, data, {
      params: query
    })
  }

  destroy ({ resource, id }) {
    return http.delete(`${resource}/${id}`)
  }
}

export default new APIProvider({
  url: env('API_URL')  // We assume 'https://api.example.com/v1' is set as the env variable
})
接下来,在您的
main.js
文件中或您引导Vue应用程序的任何地方,执行以下操作:

methods: {
 getProducts () {
     myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
  }
}
import api from '@/src/utils/api'

Vue.$api = api

Object.defineProperty(Vue.prototype, '$api', {
  get () {
    return api
  }
})
现在,您可以在Vue应用程序中的任何位置以及导入Vue本身的任何位置访问它:

<template>
  <div class="my-component">My Component</div
</template>

<script>
export default {
  name: 'MyComponent',
  data () {
    return {
      data: []
    }
  },
  async created () {
    const response = await this.$api.find({ resource: 'tasks', query: { page: 2 } })

    this.data = response.data
  }
}
</script>

希望这能有所帮助。

您可以创建自己的服务,您可以在其中放置所有HTTP服务器调用,然后将其导入到要使用它们的组件中

最好是将Vuex用于复杂的状态管理应用程序,因为在Vuex中,您可以通过始终异步运行的操作处理所有异步调用,然后在得到结果后提交变异。变异将直接与状态交互,并以不变的方式更新状态(这是首选)。这是一种有状态的方法


还有其他方法。但这些都是我在代码中遵循的原则。

根据Evan You的说法,Vue Resource将退休,转而推荐Axios。我真的很喜欢你的方法,感觉更像是有角度的2@noypeeVueResource仍然有效。但不管你想用什么,它与Axios的方法完全相同。是的,Vue2将继续容纳vue资源,根据他的文章这很好,但如何使用模拟PostsService测试这样的组件?@noype,vue资源并没有退休——埃文说他只是退休。他进一步澄清了为什么他的团队认为不再需要官方的AJAX库。链接文章对此进行了很好的解释。需要注意的是,vue资源仍在积极维护,是一个完全可行的选项。当用户登录时,您将如何更新myApi.js的X-Auth-Token?这不是一个静态值。这并没有回答OP的问题。我很惊讶它的投票率如此之高。正确的答案是Otabek KholikovIt的答案,当您可以创建一个包含状态和逻辑的TypeScript/JS类时,尝试并坚持Vuex的奇怪之处,即使用字符串文本调用服务的方法似乎非常尴尬?如何在Vue中将有状态类用作服务?对于需要与多个组件共享除组件/以外的上下文的前端,VueX不是一个好的解决方案。Angular(2.x+)服务是一个完美的例子,说明了如何在没有不必要的复杂性和过度工程的情况下实现这一点。仅供参考对于
$api
部分,在TS中,您需要执行
(Vue.prototype as any)。$api=yourobject。另外,关于该功能的v2文档也在这里:我必须说,在需要全局访问服务的情况下,该模型非常优雅?