Настройка данных для внешнего компонента Vue

Я создавал веб-приложение с использованием Vue 2.0 и отдельных файловых компонентов и столкнулся с проблемой, которую не могу понять и которую нужно решить.

В настоящее время моя соответствующая файловая структура выглядит следующим образом...

main.js

/*
 * main.js
 *
 * Initial entry point for all Vue and component code
 */

import Vue from 'vue'
import VueResource from 'vue-resource'
import App from './App.vue'
import './sockets.js'

Vue.use(VueResource)

new Vue({
  el: '#app',
  render: element => element(App)
})

сокеты.js

import App from './App.vue'

const socket = io('http://localhost:8181')

socket.on('test', payload => App.$set('test', payload))

/*socket.on('lot_change', payload => {
  console.log(payload)
  //Logic to find differences and reset
})*/

App.vue

<template>
  <div id="app">
    {{ test }}
    <template v-for="lot in allLots">
      <lot
        :uuid="lot.uuid"
        :closed="lot.closed"
        :controllerId="lot.controllerId"
        :institution="lot.institution"
        :number="lot.lotNumber"
        :permits="lot.permits"
        :taken-spaces="lot.takenSpaces"
        :total-spaces="lot.totalSpaces"></lot>
    </template>
  </div>
</template>

<script>
import Lot from './components/Lot.vue'

export default {
  data() {
    return {
      allLots: [],
      test: {}
    }
  },

  components: {
    Lot
  },

  created() {
    this.$http.get('/all').then(res => JSON.parse(res.body)).then(data => {
      this.allLots = data.results
    })
  }
}
</script>

<style>
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
</style>

При новом соединении мое приложение express отправляет событие 'test' в сокет, который отлично принимается клиентским сокетом, однако я хочу, чтобы полезная нагрузка из эмиссии внутреннего сокета и назначалась для данных компонент App.

В обратном вызове для socket.on('test') я в настоящее время получаю ошибку типа undefined function для App.$set. Я также пробовал глобальный API, используя Vue.set(App, 'test', payload), который также не работал.

Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ

Другими словами, как я могу манипулировать объектом data одного компонента файла из другого файла JS после его импорта?


person m_callens    schedule 04.10.2016    source источник


Ответы (1)


Попробуйте использовать Vuex

Похоже, вам следует подумать об использовании Vuex для этого, и его будет довольно легко настроить, хотя это кажется долгим.

Это будет базовый пример файла хранилища Vuex:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    allLots: []
  },
  getters: {
    lots: state => {
      return state.allLots
    }
  },
  mutations: {
    setAllLots (state, lots) {
      state.allLots = lots
    }
  },
  actions: {
    setAllLots ({ commit }, lots) {
      commit('setAllLots', lots)
    }
  }
})

В вашем файле main.js:

import store as './your-path/store'

и обновить ниже:

new Vue({
  el: '#app',
  store,
  render: element => element(App)
})

Это устанавливает vuex с вашим экземпляром vue. Теперь вам нужно будет обновить данные allLots в vuex, вызвав функцию диспетчеризации магазина в вашем запросе, чтобы получить лоты в App.vue...

Импортируйте store в App.vue аналогично тому, что вы делали в main.js, и обновите этот код:

created() {
    this.$http.get('/all').then(res => JSON.parse(res.body)).then(data => {
      store.dispatch('setAllLots', data.results)
    })
  }

Итак, что будет сделано, так это отправить data.results в качестве параметра lots в действие вашего магазина: setAllLots

...который фиксирует параметр lots в мутации вашего магазина: setAllLots

... который обновляет ваши данные allLots с параметром lots

Теперь, когда vuex обновлен, вы можете получить эту информацию везде, где ваш магазин импортирован, с помощью геттера lots.

Итак, чтобы получить его в своем App.vue, используйте вычисляемое свойство (заменяет allLots в ваших возвращаемых данных) следующим образом:

computed: {
  allLots () {
    return store.getters.lots
  }
}

Ваш allLots теперь будет отображаться в вашем шаблоне из вычисляемого свойства.

Мой первый ответ на это был неверным, потому что я изначально неправильно понял вашу проблему, но понял, что это все еще должно работать.

Попробуйте еще раз импортировать store и вызвать:

socket.on('test', payload => store.dispatch('setAllLots', payload))

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

В любом случае, я надеюсь, что это поможет вам или кому-либо еще с быстрой настройкой Vuex.

person Collier Devlin    schedule 21.11.2016