Що еквівалентно Angular Service у VueJS?


95

Я хочу помістити всі свої функції, які розмовляють із сервером та отримувати дані, в один файл багаторазового використання у VueJS.

Здається, плагіни не є найкращою альтернативою. Шаблон менше компонентів ..?

Відповіді:


58

Всього існує 4 способи:

  • Служба без громадянства: тоді вам слід використовувати міксини
  • Сервіс із підтримкою стану: використовуйте Vuex
  • Експорт послуги та імпорт з коду vue
  • будь-який глобальний об'єкт javascript

4
Дуже незручно намагатися дотримуватися дивацтв Vuex виклику методів із рядковими літералами для служб, коли ви можете створити клас TypeScript / JS, що містить стан та логіку для нього? Як ви можете використовувати клас, що містить статус, як послугу в 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 - це гнучкий спосіб розподілу функцій багаторазового використання для компонентів Vue. Об’єкт змішування може містити будь-які варіанти компонентів. Коли компонент використовує міксин, усі варіанти мікшину будуть “змішані” з власними опціями компонента.

Таким чином, ви можете додати метод до міксину, і він буде доступний у всіх компонентах, де міксин буде змішуватися. Дивіться наступний приклад:

// 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
як ви оновите X-Auth-Token з myApi.js, коли користувач увійде в систему
Amarjit Singh

3
зазвичай це не статичне значення
Амарджіт Сінгх

30

В основному я використовую Vue Resource.

1.Я створюю новий файл, де я підключаюся до кінцевої точки 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
За словами Евана Ю, Vue-Resource піде на пенсію і замість цього рекомендує Axios. Прочитайте його статтю. Мені дуже подобається ваш підхід, який більше схожий на кутовий 2
річний

@noypee VueResource все ще працює, але неважливо використовуйте те, що ви хочете, це буде точно такий же підхід з Axios.
Белмін Бедак

1
Так, Vue2 продовжуватиме розміщувати vue-ресурс також згідно зі своєю статтею
шифровано

2
Це дуже приємно, але як протестувати такий компонент за допомогою mock-PostsService?
Шрайк

@noypee, vue-resource не припиняється - Еван заявив, що він просто "вилучає його зі статусу офіційної рекомендації" . Далі він пояснив, чому його команда дійшла висновку, що більше немає необхідності в офіційній бібліотеці AJAX. Пов’язана стаття це добре пояснює. І слід зазначити, що vue-ресурс досі активно підтримується і є цілком життєздатним варіантом.
squidbe

8

Я пропоную створити постачальника API, до якого ви можете отримати доступ з будь-якої точки вашого додатка.

Просто створіть src/utilsпапку і всередині неї файл з назвою api.js.

У ньому експортуйте вашу обгортку, яка знає, як взаємодіяти з вашим API як об’єкт або статичний клас ES6 (я віддаю перевагу тому, як останній виглядає та працює, якщо ви не боїтесь класів). Цей постачальник може використовувати будь-яку вподобану вам бібліотеку запитів HTTP, і ви можете легко поміняти її місцями згодом, змінивши один файл (цей), замість того, щоб шукати всю кодову базу. Ось приклад використання axios, припускаючи, що у нас є REST API, api.example.com/v1який використовує SSL:

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 ви можете обробляти всі асинхронні виклики за допомогою дій, які завжди виконуються асинхронно, а потім здійснювати мутацію, як тільки ви отримаєте результат. це незмінним чином (що є кращим). Це державний підхід.

Є й інші підходи. Але це те, чого я дотримуюсь у своєму коді.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.