VueJS中的Angular Service相当于什么?


95

我想将所有与服务器通信并将函数获取数据的功能放入VueJS中的单个可重用文件中。

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

Answers:


57

总共有4种方法:

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

4
当您可以使TypeScript / JS类包含状态和逻辑时,尝试坚持使用带有字符串文字的服务来调用方法的Vuex怪事似乎很尴尬?您如何在Vue中将有状态类用作服务?
道格拉斯·加斯凯尔

37

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

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)
  }
}

我假设您想在多个组件中重用此方法,因此可以使用vue.js的mixins

Mixins是为Vue组件分发可重用功能的灵活方法。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')
  }
})

3
用户登录时,如何更新myApi.js的X-Auth-Token
Amarjit Singh

3
通常这不是一个静态值
Amarjit Singh

30

我主要使用Vue资源。

1,我创建了一个新文件,用于使用API​​连接到API端点Vue.http.xxx。假设我们有端点输出帖子。在您的项目中创建新目录,我将其命名为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 https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app上查看我的仓库


7
根据Evan You的说法,Vue-Resource将退休,并推荐Axios。阅读他的文章, 我真的很喜欢您的方法,感觉更像是角度2
编码为

@noypee VueResource仍然可以使用。但是没关系使用您想要的东西,这与Axios完全相同。
Belmin Bedak

1
是的,Vue2将继续以适应VUE资源以及按他的文章是
codely

2
这很好,但是如何使用模拟PostsService测试这样的组件?
伯劳

@ noypee,vue-resource尚未退休-Evan表示他只是“从官方推荐状态中退休”。他进一步阐明了为什么他的团队得出结论,不再需要正式的AJAX库。链接的文章对此进行了很好的解释。应当指出的是,vue-source仍在积极维护中,并且是一个完全可行的选择。
squidbe

8

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

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

在其中,导出知道如何与API通信的包装器作为对象或ES6静态类(我更喜欢后者在不怕类的情况下的外观和工作方式)。该提供程序可以使用您喜欢的任何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应用程序的位置,执行以下操作:

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>

要么:

// actions.js from Vuex
import Vue from 'vue'

export async function fetchTasks ({ commit }) {
  const response = await Vue.$api.find({ resource: 'tasks', query: { page: 2 } })

  commit('SAVE_TASKS', response.data)

  return response
}

希望这可以帮助。


3

我认为对于您的简单问题,答案可能是任何包含函数的ES6模块(等同于ANgular中的类中的方法),并使用ES6导入和导出将其直接导入组件中。没有可以在组件中注入的服务。


1

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.