Tương đương với Dịch vụ Angular trong VueJS là gì?


95

Tôi muốn đặt tất cả các chức năng của mình nói chuyện với máy chủ và tìm nạp dữ liệu vào một tệp có thể sử dụng lại duy nhất trong VueJS.

Các plugin dường như không phải là giải pháp thay thế tốt nhất. Template ít thành phần hơn ..?

Câu trả lời:


58

Tổng cộng có 4 cách:

  • Dịch vụ không trạng thái: thì bạn nên sử dụng mixin
  • Dịch vụ nhà nước: sử dụng Vuex
  • Dịch vụ xuất và nhập từ mã vue
  • bất kỳ đối tượng toàn cầu javascript nào

4
Có vẻ rất khó xử khi thử và tuân thủ những điều kỳ lạ Vuex khi gọi các phương thức với chuỗi ký tự cho các dịch vụ khi bạn có thể tạo một lớp TypeScript / JS có chứa trạng thái và logic cho nó? Làm thế nào bạn có thể sử dụng một lớp trạng thái như một dịch vụ trong Vue?
Douglas Gaskell

37

Tôi đang sử dụng axios làm ứng dụng khách HTTP để thực hiện các cuộc gọi api, tôi đã tạo một gatewaysthư mục trong srcthư mục của mình và tôi đã đặt các tệp cho mỗi chương trình phụ trợ, tạo các phiên bản axios , như sau

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

Bây giờ trong thành phần của bạn, Bạn có thể có một hàm sẽ lấy dữ liệu từ api như sau:

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

Như tôi giả sử bạn muốn tái sử dụng phương pháp này trong nhiều thành phần, bạn có thể sử dụng mixins của vue.js:

Mixin là một cách linh hoạt để phân phối các chức năng có thể tái sử dụng cho các thành phần Vue. Một đối tượng mixin có thể chứa bất kỳ tùy chọn thành phần nào. Khi một thành phần sử dụng một mixin, tất cả các tùy chọn trong mixin sẽ được "trộn" vào các tùy chọn riêng của thành phần.

Vì vậy, bạn có thể thêm một phương thức trong mixin và nó sẽ có sẵn trong tất cả các thành phần, nơi mixin sẽ được trộn. Xem ví dụ sau:

// 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
làm thế nào bạn sẽ cập nhật X-Auth-Token of myApi.js khi người dùng sẽ đăng nhập
Amarjit Singh

3
thường thì đây không phải là giá trị tĩnh
Amarjit Singh

30

Tôi chủ yếu sử dụng Vue Resource.

1.Tôi tạo tệp mới trong đó tôi thực hiện kết nối với điểm cuối API bằng cách sử dụng Vue.http.xxx. Vì vậy, giả sử chúng tôi có điểm cuối xuất các bài đăng. Tạo thư mục mới trong dự án của bạn, tôi gọi nó servicesvà sau đó tạo tệp có tên PostsService.js- nội dung giống như sau:

import Vue from 'vue'

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

Sau đó, tôi đi đến thành phần mà tôi muốn sử dụng dịch vụ này và nhập nó

import PostsService from '../services/PostsService'

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

Để biết thêm thông tin về phương pháp này, vui lòng kiểm tra repo của tôi trên GitHub https://github.com/bedakb/vuewp/tree/master/public/app/themes/vuewp/app


7
Theo Evan You, Vue-Resource sẽ ngừng hoạt động và đề xuất Axios thay thế. Đọc bài viết của anh tôi thực sự thích cách tiếp cận của bạn mà cảm thấy giống như góc 2
codely

@noypee VueResource vẫn hoạt động, nhưng đừng bận tâm sử dụng những gì bạn muốn, nó sẽ giống hệt cách tiếp cận với Axios.
Belmin Bedak

1
Có, Vue2 sẽ tiếp tục cung cấp vue-resource theo bài viết của anh ấy
từ

2
Điều này rất hay nhưng làm thế nào để kiểm tra một thành phần như vậy với mock-PostsService?
Shrike

@noypee, vue-resource sẽ không bị gỡ bỏ - Evan nói rằng anh ấy chỉ "loại bỏ nó khỏi trạng thái đề xuất chính thức" . Ông làm rõ thêm tại sao nhóm của ông kết luận rằng không còn cần thiết phải có thư viện AJAX chính thức. Bài báo được liên kết giải thích nó tốt. Và cần lưu ý rằng vue-resource vẫn đang được duy trì tích cực và là một lựa chọn hoàn toàn khả thi.
inkbe

8

Tôi khuyên bạn nên tạo Nhà cung cấp API mà bạn có thể truy cập từ bất kỳ đâu trong ứng dụng của mình.

Đơn giản chỉ cần tạo một src/utilsthư mục và bên trong nó là một tệp có tên api.js.

Trong đó, xuất trình bao bọc của bạn biết cách giao tiếp với API của bạn dưới dạng một đối tượng hoặc một lớp tĩnh ES6 (Tôi thích cách thức sau này trông và hoạt động nếu bạn không sợ các lớp). Nhà cung cấp này có thể sử dụng bất kỳ thư viện yêu cầu HTTP nào mà bạn thích và bạn có thể dễ dàng hoán đổi nó sau này bằng cách thay đổi một tệp duy nhất (tệp này) thay vì tìm kiếm toàn bộ cơ sở mã. Dưới đây là một ví dụ về việc sử dụng axios, giả sử chúng ta có sẵn API REST api.example.com/v1sử dụng 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
})

Tiếp theo, trong main.jstệp của bạn hoặc bất kỳ nơi nào khác mà bạn khởi động ứng dụng Vue, hãy làm như sau:

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

Vue.$api = api

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

Giờ đây, bạn có thể truy cập nó ở bất kỳ đâu trong ứng dụng Vue của mình cũng như bất kỳ nơi nào bạn nhập chính 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>

hoặc là:

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

Hi vọng điêu nay co ich.


3

Tôi nghĩ rằng đối với câu hỏi đơn giản của bạn, câu trả lời có thể là bất kỳ mô-đun ES6 nào có chứa các hàm (tương đương với các phương thức trong lớp trong ANgular) và nhập trực tiếp chúng vào các thành phần bằng cách sử dụng nhập và xuất ES6. Không có dịch vụ nào như vậy có thể được đưa vào các thành phần.


1

Bạn có thể tạo dịch vụ của riêng mình, nơi bạn có thể đặt tất cả các cuộc gọi máy chủ HTTP của mình và sau đó nhập nó vào các thành phần mà bạn muốn sử dụng chúng.

Tốt nhất là sử dụng Vuex cho các ứng dụng quản lý trạng thái phức tạp vì trong Vuex, bạn có thể xử lý tất cả các lệnh gọi không đồng bộ thông qua các hành động luôn chạy không đồng bộ và sau đó thực hiện đột biến khi bạn có kết quả. nó theo cách bất biến (được ưu tiên hơn). Đây là cách tiếp cận trạng thái.

Cũng có những cách tiếp cận khác. Nhưng đây là những cái mà tôi theo dõi trong mã của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.