Apa yang setara dengan Angular Service di VueJS?

99

Saya ingin meletakkan semua fungsi saya yang berbicara ke server dan mengambil data ke dalam satu file yang dapat digunakan kembali di VueJS.

Plugin tampaknya bukan alternatif terbaik. Template lebih sedikit komponen ..?

Faizuddin Mohammed
sumber

Jawaban:

61

Total ada 4 cara:

  • Layanan stateless: maka Anda harus menggunakan mixin
  • Layanan stateful: gunakan Vuex
  • Layanan ekspor dan impor dari kode vue
  • objek global javascript apa pun
Otabek Kholikov
sumber
6
Tampaknya sangat canggung untuk mencoba dan mematuhi keanehan Vuex dalam memanggil metode dengan literal string untuk layanan ketika Anda dapat membuat kelas TypeScript / JS yang berisi status dan logika untuk itu? Bagaimana Anda bisa menggunakan kelas stateful sebagai layanan dalam Vue?
Douglas Gaskell
VueX bukanlah solusi yang baik untuk frontend yang membutuhkan konteks selain komponen / untuk dibagikan dengan banyak komponen. The Angular (2.x +) Service adalah contoh sempurna tentang bagaimana mencapai ini tanpa kerumitan yang tidak perlu dan rekayasa berlebihan.
Kody
37

Saya menggunakan axios sebagai klien HTTP untuk membuat panggilan api, saya telah membuat gatewaysfolder di srcfolder saya dan saya telah meletakkan file untuk setiap backend, membuat contoh axios , seperti berikut

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

Sekarang di komponen Anda, Anda dapat memiliki fungsi yang akan mengambil data dari api seperti berikut:

methods: {
 getProducts () {
     myApi.get('products?id=' + prodId).then(response =>  this.product = response.data)
  }
}

Seperti yang saya menganggap Anda ingin kembali menggunakan metode ini dalam beberapa komponen, Anda dapat menggunakan mixin dari vue.js:

Mixin adalah cara fleksibel untuk mendistribusikan fungsionalitas yang dapat digunakan kembali untuk komponen Vue. Objek mixin dapat berisi opsi komponen apa pun. Saat komponen menggunakan mixin, semua opsi di mixin akan "dicampur" ke dalam opsi komponen itu sendiri.

Jadi Anda bisa menambahkan metode di mixin dan itu akan tersedia di semua komponen, di mana mixin akan dicampur. Lihat contoh berikut:

// 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')
  }
})
Saurabh
sumber
3
bagaimana Anda memperbarui X-Auth-Token dari myApi.js ketika pengguna akan masuk
Amarjit Singh
3
biasanya ini bukan nilai statis
Amarjit Singh
30

Saya kebanyakan menggunakan Vue Resource.

1.Saya membuat file baru di mana saya melakukan koneksi ke titik akhir API menggunakan Vue.http.xxx. Jadi katakanlah kita memiliki titik akhir yang menampilkan posting. Buat direktori baru di proyek Anda, saya menyebutnya services, dan kemudian buat file bernama PostsService.js- konten terlihat seperti ini:

import Vue from 'vue'

export default {
  get() {
    return Vue.http.get('/api/posts)
  }
}

Lalu saya pergi ke komponen tempat saya ingin menggunakan layanan ini, dan mengimpornya

import PostsService from '../services/PostsService'

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

Untuk info lebih lanjut tentang pendekatan ini, silakan periksa repo saya di GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app

Belmin Bedak
sumber
7
Menurut Evan You, Vue-Resource akan dihentikan dan merekomendasikan Axios sebagai gantinya. Baca artikelnya Saya sangat suka pendekatan Anda yang terasa lebih bersudut 2
codely
@noypee VueResource masih berfungsi. Tapi tidak masalah menggunakan apa yang Anda inginkan, itu akan menjadi pendekatan yang persis sama dengan Axios.
Belmin Bedak
1
Ya, Vue2 juga akan terus mengakomodasi vue-resource sesuai artikelnya
codely
2
Ini sangat bagus, tetapi bagaimana cara menguji komponen seperti itu dengan mock-PostsService?
Shrike
@noypee, vue-resource tidak dihentikan - Evan menyatakan bahwa dia hanya "menghentikannya dari status rekomendasi resmi" . Dia lebih lanjut mengklarifikasi mengapa timnya menyimpulkan bahwa perpustakaan AJAX resmi tidak lagi dibutuhkan. Artikel terkait menjelaskannya dengan baik. Dan perlu dicatat bahwa vue-resource masih dipertahankan secara aktif dan merupakan opsi yang sangat layak.
squidbe
8

Saya sarankan membuat Penyedia API yang dapat Anda akses dari mana saja di aplikasi Anda.

Cukup buat src/utilsfolder dan di dalamnya ada file bernama api.js.

Di dalamnya, ekspor pembungkus Anda yang tahu cara berkomunikasi dengan API Anda sebagai objek atau kelas statis ES6 (saya lebih suka bagaimana yang terakhir terlihat dan berfungsi jika Anda tidak takut dengan kelas). Penyedia ini dapat menggunakan pustaka permintaan HTTP apa pun yang Anda suka dan Anda dapat dengan mudah menukarnya nanti dengan mengubah satu file (yang ini) alih-alih memburu seluruh basis kode. Berikut adalah contoh penggunaan axios, dengan asumsi kami memiliki REST API yang tersedia api.example.com/v1yang menggunakan 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
})

Selanjutnya, di main.jsfile Anda atau di mana pun Anda melakukan bootstrap aplikasi Vue, lakukan hal berikut:

import api from '@/src/utils/api'

Vue.$api = api

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

Sekarang Anda dapat mengaksesnya di mana saja di aplikasi Vue Anda serta di mana pun Anda mengimpor Vue itu sendiri:

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

atau:

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

Semoga ini membantu.

teknisi
sumber
3

Saya pikir untuk pertanyaan sederhana Anda jawabannya bisa berupa modul ES6 yang berisi fungsi (setara dengan metode di kelas di ANgular) dan langsung mengimpornya dalam komponen menggunakan impor dan ekspor ES6. Tidak ada layanan seperti itu yang bisa disuntikkan ke dalam komponen.

Sourabh Ranka
sumber
1

Anda dapat membuat layanan Anda sendiri di mana Anda dapat menempatkan semua panggilan server HTTP Anda dan kemudian mengimpornya ke komponen tempat Anda ingin menggunakannya.

Yang terbaik adalah menggunakan Vuex untuk aplikasi manajemen status yang kompleks karena di Vuex Anda dapat menangani semua panggilan asinkron melalui tindakan yang selalu berjalan secara asinkron dan kemudian melakukan mutasi setelah Anda mendapatkan hasilnya. Mutasi akan langsung berinteraksi dengan status dan akan memperbarui itu dengan cara yang tidak berubah (yang lebih disukai). Ini adalah pendekatan stateful.

Ada pendekatan lain juga. Tapi ini adalah yang saya ikuti dalam kode saya.

Prateek Madaan
sumber