Vue.js: определение службы

90

Я смотрю на Vue.js как на альтернативу Angular, и пока мне он очень нравится. Чтобы прочувствовать это, я реорганизую существующий проект Angular в проект Vue. Я как раз в той точке, где мне нужно связаться с моим REST API.

В Angular я использовал для этого службу, которая вводилась в каждый контроллер, который в ней нуждался. Насколько я понимаю, Vue, похоже, не знает конструкцию «служба». Как этого добиться во Vue?

Я подумал vue-resource, но, насколько я понимаю, это только для функций http. Поскольку я тоже использую jQuery, это устарело.

Пример:

У меня есть vueComponent1и vueComponent2. Обоим нужен доступ к одному и тому же ресурсу REST. Чтобы справиться с этим, мне нужна центральная служба, которую оба компонента могут использовать для запросов к ресурсу REST. В Angular есть служебный компонент, который именно этим и занимается. Vue этого не сделал.

Герр Дерб
источник
Приведите конкретный пример того, что вам нужно. http достаточно для связи с REST
gurghet
Взгляните на vue-resource: github.com/vuejs/vue-resource
nils

Ответы:

98

Из документации Vue.js.

Сам Vue.js не является полноценным фреймворком - он ориентирован только на уровень представления.

Как библиотека, ориентированная на V из MVC, она не предоставляет такие вещи, как услуги.

Вы используете какой-нибудь загрузчик модулей, например Browserify или Webpack?
Затем вы можете использовать модульную систему ES6 для самостоятельного создания службы.
Все, что вам нужно сделать, это создать простой класс JavaScript, который экспортируется этим новым модулем.

Пример может выглядеть так:

export default class RestResource {

  sendRequest() {
    // Use vue-resource or any other http library to send your request
  }

}

Внутри компонентов vue 1 и 2 вы можете использовать эту службу, импортировав класс.

import RestResource from './services/RestResource';

const restResourceService = new RestResource();

restResourceService.sendRequest();
Марк
источник
2
Спасибо за цитату. Это означает, что под видом и моделью нет структуры или чего-либо еще. Если я хочу иметь службу, мне нужно создать свою собственную, например, используя чистый JS.
Herr Derb
Я получаю, movieslist.vue?1be4:38Uncaught TypeError: _resource.Resource is not a constructorкогда использую это ...
Джордж Катсанос
14
Вам не хватает одного существенного отличия от того, что вы ожидаете от фона Angular. В этом случае «служба» создается несколько раз, тогда как при внедрении общей службы передается только один экземпляр
phil294
2
Да, таким образом вы получаете несколько экземпляров одной и той же службы. Это не проблема, когда он просто выполняет запрос Ajax (просто неэффективно), но когда вы используете службу для своей модели данных, вам нужно создать ее экземпляр там, где вы объявляете службу, и экспортировать только экземпляр.
mcv 04
5
Если вам нужна одноэлементная служба «Angular style», вы можете просто создать экземпляр этого класса где-нибудь в своем приложении и экспортировать его: export const restResourceService = new RestResource();а затем импортировать в любое место. Однако это действительно решение проблемы, которую мы сами для себя создали - почему бы просто не использовать функцию? export function sendRequest() { // Make the request } Наконец, обратите внимание, что вам не обязательно даже нужна библиотека для выполнения HTTP-запроса - в зависимости от требований вашего проекта вы можете просто использовать JavaScript fetchAPI.
Уилл Тейлор
22

Из документации Vue.js по созданию крупномасштабных приложений .

Сообщество предоставило плагин vue-resource , который обеспечивает простой способ работы с RESTful API. Вы также можете использовать любую понравившуюся библиотеку Ajax, например $ .ajax или SuperAgent .

Vue не требует, чтобы вы следовали определенной архитектуре, поскольку он относится только к уровню представления в архитектуре MVC или MVVM. Как уже сказал @Marc в своем ответе , хорошей практикой является использование загрузчика модулей, например Browserify или Webpack, чтобы вы могли создавать свои «службы» в отдельных файлах, импортируя их туда, где вам нужно. Структурировать приложение с помощью загрузчика модулей очень легко с помощью vue-cli .

Действительно, мне лично очень нравится архитектура Flux для приложений на основе компонентов, поэтому я рекомендую вам взглянуть на Vuex , архитектуру приложений, основанную на Flux, которая разработана специально для управления состоянием внутри приложений Vue.js.

Таким образом, вы можете создавать действия, которые используют vue-resource для запроса вашего API, а затем вы можете отправлять мутации по прибытии данных, при этом все компоненты, которым эти данные уже привязаны к глобальному состоянию, будут реагировать автоматически. Другими словами, вашим компонентам не нужно вызывать службы, они просто реагируют на изменения состояния, отправленные Mutations.

Эрик Петручелли
источник
4
Замечу, что vue-resource больше не рекомендуется официально. источник
lightswitch05 09
1
Ознакомьтесь с подробностями: уходящий на пенсию vue-ресурс, написанный Эваном
Ю
1
В настоящее время рекомендуется использовать Axios вместо vue-resource.
Луис Мартин,
19

Вы можете экспортировать экземпляр класса для своей службы:

export default new class {
   ...
}

В своем компоненте или в любом другом месте вы можете импортировать экземпляр, и вы всегда будете получать один и тот же. Таким образом, он ведет себя аналогично внедренной службе Angular, но без использования this.

import myService from '../services/myservice';

Vue.component('my-component', {
  ...
  created: function() {
    myService.oneFunction();
  }
  ...
})
Макс Ориола
источник
12

У вас есть очень хорошие ответы на этот вопрос. Что эквивалентно Angular Service в VueJS?

Как говорит там @Otabek Kholikov - у вас есть 4 варианта:

  1. Сервис без сохранения состояния: тогда вам следует использовать миксины
  2. Служба Statefull: используйте Vuex
  3. Служба экспорта и импорт из кода vue
  4. любой глобальный объект javascript

В своих проектах предпочитаю (4). Он дает мне максимальную гибкость и имеет только те реализации, которые мне нужны (я не беру, например, Vuex, не должен строго придерживаться его правил, и здесь нет «магии» - весь код мой). У вас есть пример реализации в упомянутом выше вопросе .

Александр
источник
6

Если вы не используете загрузчик модулей, вы можете определить собственный плагин . Пример кода:

var myPlugin = {
        install: function (Vue, options) {
            //private
            var myPrivateProperty = 'Private property';

            //instance properties and methods
            Vue.prototype.$myPublicProperty = 'Public Property';

            Vue.prototype.$myAddedMethod = function () {
                return myPrivateProperty;
            };
            Vue.prototype._getData = function (url) {
                return url;
            };

            //static properties and methods
            Vue.myStaticProperty = 'My static prop';
            Vue.myStaticMethod = function () {
                console.log('in');
            }
        }
    };

    Vue.use(myPlugin);

    new Vue({
        el: '#app',
        created: function () {
            //using instance
            console.log(this.$myAddedMethod());
            console.log('my get data: ' + this._getData('some url'));
            console.log(this.$myPublicProperty);

            //using static
            console.log(Vue.myStaticProperty);
            Vue.myStaticMethod();
        }
    });

Вы также можете подключить другие библиотеки, в этом посте показано, как подключить axios.js

Майкл Транчида
источник
1

Вы можете настроить ресурс vue глобально как

Vue.http.options.root = "your base url"

и теперь при каждом http-вызове вы можете просто вызывать по имени ресурса -

this.$http.get('');
this.$http.get('users')
Сураб Ранка
источник