импортированный модуль vue.js не определен внутри обратного вызова - PullRequest
1 голос
/ 30 сентября 2019

Я использую простую реализацию, похожую на магазин, в своем приложении vue.js. Я определил магазин следующим образом:

     // File: my_store.js
     var invoiceDetailStore = {

        state: {
           selectedInvoiceId: null,
           selectedInvoiceDetails: {}
        },

        setSelectedInvoiceId(selectedId, comp) {
           console.log('selectedInvoiceId updated by ' + comp + ' with value ' + selectedId);
           this.state.selectedInvoiceId = selectedId;
        },

        setSelectedInvoiceDetails: (invoiceDetails, comp) => {
           console.log('selectedInvoiceDetails updated by ' + comp + ' with value ' + invoiceDetails);
           this.selectedInvoiceDetails = invoiceDetails;
        },

        addSelectedInvoiceDetail: (invoiceDetail, comp) => {
           console.log('InvoiceDetail added by ' + comp + ' with value ' + invoiceDetail);
           this.selectedInvoiceDetails.push(invoiceDetail);
        }
     };

     export { invoiceDetailStore };

В моем компоненте я импортировал магазин. Когда отслеживаемое свойство изменяется в компоненте, я делаю вызов axios, а затем пытаюсь вызвать метод в хранилище внутри успешного обратного вызова axios, например:

 // mycomponent.vue
 import { invoiceDetailStore } from '../Shared_State/invoice_detail_store.js';

 export default {
 data() {
     return {
        shared: invoiceDetailStore.state,
        selectedInvoice: {},
     };
  },

  mounted: function() {
     console.log(invoiceDetailStore);   // This prints the store properties and functions....
  },
  watch: {
     selectedInvoiceId: function(newValue, oldValue) {
        console.log(invoiceDetailStore);    // THIS prints undefined
        if(newValue !== oldValue) {
           axios('my/get/url')
           .then(response => {
              this.selectedInvoice = response.data.invoice_summary; // it sets the local data property called selectedInvoice 
              invoiceDetailStore.setSelectedInvoiceDetails(response.data.invoice_details);   // .......... invoiceDetailStore is undefined
           })
           .catch(errorResponse => {
             // error actions here
           });
        }
     }
  },
}

Как видно из комментариевЯ получаю Cannot read property 'setSelectedInvoiceDetails' of undefined. Тем не менее, invoiceDetailStore не является неопределенным внутри установленного крюка.

Может кто-нибудь, пожалуйста, направить в правильном направлении?

Спасибо

Ответы [ 2 ]

1 голос
/ 30 сентября 2019

По запросу, вот мой комментарий в качестве ответа. Я подчеркиваю, что, хотя это исправляет важные ошибки в вашем коде, я не вижу причин, по которым он мог бы обратиться к конкретному сообщению об ошибке, опубликованному в вопросе.

У вас есть несколько функций в вашем «магазине», как это:

setSelectedInvoiceDetails: (invoiceDetails, comp) => {
    console.log('selectedInvoiceDetails updated by ' + comp + ' with value ' + invoiceDetails);
    this.selectedInvoiceDetails = invoiceDetails;
},

Так как при использовании функции со стрелкой будет использоваться неправильное значение this. Кроме того, он не обращается к selectedInvoiceDetails через state. Я считаю, что это должно быть изменено на:

setSelectedInvoiceDetails (invoiceDetails, comp) {
    console.log('selectedInvoiceDetails updated by ' + comp + ' with value ' + invoiceDetails);
    this.state.selectedInvoiceDetails = invoiceDetails;
},

Я бы предложил провести дальнейшее расследование, чтобы установить, почему это, похоже, решает проблему. Например, это может быть из-за того, что вы работали с кэшированной версией кода, а указанное выше изменение просто очистило этот кеш.

1 голос
/ 30 сентября 2019

Не следует импортировать магазин в один компонент.

Vuex предоставляет механизм для «вставки» хранилища во все дочерние компоненты из корневого компонента с помощью опции хранилища (включается Vue.use (Vuex))

Таким образом, вы импортируете хранилище только тогда, когда создаете свой корневой экземпляр vue и передаете его в конструктор. Вот пример из документации.

const app = new Vue({
  el: '#app',
  // provide the store using the "store" option.
  // this will inject the store instance to all child components.
  store,
  components: { Counter },
  template: `
    <div class="app">
       <counter></counter>
    </div>
  `
});

Vue.use(Vuex)

При предоставлении опции хранилища корневому экземпляру хранилище будет внедрено во все дочерние компоненты корня и будет доступно на них, как это. $ store.

Также помните, что между function() {} и () => {} есть разница. Первый из них создаст собственную область видимости, а второй - область своих родителей. Многие проблемы в Vue, связанные с неопределенными переменными в области действия или неопределенным ключевым словом this, связаны с этим и могут быть решены с помощью () => {}.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...