Значения, которые не вступили в силу после того, как стали доступны в Vuex Store

1

Поэтому я извлекаю свои данные из своего api, используя vue-resource который происходит правильно, состояние обновляется, и из консоли я могу видеть значения, которые я запрашиваю. Моя проблема заключается в том, что когда приложение загружает данные из хранилища, похоже, не влияет на приложение при загрузке, но если, например, я меняю страницы, информация отображается правильно. Это заставляет меня верить где-то по пути, когда я неправильно использовал крючки жизненного цикла, или я неправильно обработал состояние внутри vuex.

Магазин Vuex

import Vue from 'vue'
import Vuex from 'vuex'
import VueResource from 'vue-resource'

Vue.use(VueResource)
Vue.use(Vuex)

const state = {
  twitter: 0,
  instagram: 0,
  youtube: 0,
  twitch: 0
}

const actions = {
  LOAD_METRICS: ({commit}) => {
    Vue.http.get('http://109.74.195.166:2000/metrics').then(response => {
      let out = [{
        twitter: Number(response.body[0].twitter),
        instagram: Number(response.body[0].instagram),
        youtube: Number(response.body[0].youtube),
        twitch: Number(response.body[0].twitch)
      }]
      commit('SET_METRICS', out)
    }).catch((e) => {
      console.log(e)
    })
  }
}

const mutations = {
  SET_METRICS (state, obj) {
    state.twitter = obj[0].twitter
    state.instagram = obj[0].instagram
    state.youtube = obj[0].youtube
    state.twitch = obj[0].twitch
  }
}

const getters = {}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

Здесь я пытаюсь отправить событие, чтобы собрать необходимую информацию, используя мутацию.

<template>
  <div id="app">
    <NavigationTop></NavigationTop>
    <router-view></router-view>
    <SocialBar></SocialBar>
    <CopyrightBar></CopyrightBar>
  </div>
</template>

<script>

  export default {
    name: 'app',
    ready: function () {
      this.$store.dispatch('LOAD_METRICS')
    }
  }
</script>

<style>
  @import url('https://fonts.googleapis.com/css?family=Roboto:400,700,900');

  #app {
    font-family: 'Roboto', sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: white;
    background: url('./assets/Images/bodyBackground.jpg');
  }
</style>

Затем, наконец, я запрашиваю информацию внутри компонента, которая будет использоваться countup.js, а также давая ее методу внутри данных.

<template>
  <div class="hero">
    <div class="container hero-content">
      <div class="row hero-back align-items-end">
        <div class="col-lg-6">
          <div class="row">
            <div class="col-lg-6" v-for="icons in socialIcons">
              <Hero-Tile
                :name="icons.name"
                :icon="icons.iconName"
                :count="icons.count"
                :numeric="icons.numeric"
              ></Hero-Tile>
              <h1>{{origin}}</h1>
            </div>
          </div>
        </div>
      </div>

    </div>
    <div class="diagonal-left-lines"></div>
    <div class="home-hero-img"><img class="img-fluid" src="../../assets/Images/home-hero.jpg"></div>
  </div>
</template>

<script>
  import HeroTile from './Hero-Tile'
  import CountUp from 'countup.js'

  export default {
    components: {HeroTile},
    name: 'hero',
    data () {
      return {
        origin: '',
        socialIcons: [
          {
            name: 'twitter',
            iconName: 'twitter',
            count: this.$store.state.twitter,
            numeric: 26000
          },
          {
            name: 'instagram',
            iconName: 'instagram',
            count: this.$store.state.instagram,
            numeric: 35000
          },
          {
            name: 'youtube',
            iconName: 'youtube-play',
            count: this.$store.state.youtube,
            numeric: 15000
          },
          {
            name: 'twitch',
            iconName: 'twitch',
            count: this.$store.state.twitch,
            numeric: 127000
          }
        ]
      }
    },
    methods: {
      updateNumbers: function () {
        let options = {
          useEasing: true,
          useGrouping: true,
          separator: ',',
          decimal: '.',
          prefix: '',
          suffix: 'K'
        }

        function kFormatter (num) {
          return num > 999 ? (num / 1000).toFixed(1) : num
        }

        let twitter = new CountUp('twitter', 0, kFormatter(this.$store.state.twitter), 0, 3, options)
        let instagram = new CountUp('instagram', 0, kFormatter(this.$store.state.instagram), 0, 3, options)
        let youtube = new CountUp('youtube', 0, kFormatter(this.$store.state.youtube), 0, 3, options)
        let twitch = new CountUp('twitch', 0, kFormatter(this.$store.state.twitch), 0, 3, options)
        twitter.start()
        instagram.start()
        youtube.start()
        twitch.start()
      }
    },
    mounted: function () {
      this.updateNumbers()
    }
  }
</script>

Чтобы быть ясным на данный момент, кажется, что просто загружает "0k", так что, как будто существует какая-то форма состояния гонки, вызывающая ее не фактическую загрузку информации о загрузке. Хотя я не уверен, какой правильный подход здесь.

Теги:
vue.js
vuejs2
vuex

1 ответ

0
Лучший ответ

Это было в конечном итоге решено тем, что я буду описывать как взломать, поскольку я на самом деле не знаю точного правильного ответа в это время. Хотя то, что у меня есть, работает.

Достопримечательности ниже:

хранить

LOAD_METRICS: ({commit}, context) => {
    console.log(context)
    if (context === true) {
      return new Promise((resolve) => {
        resolve('loaded')
      })
    }
    return new Promise((resolve) => {
      Vue.http.get('real ip is normally here').then(response => {
        let out = {
          twitter: Number(response.body[0].twitter),
          instagram: Number(response.body[0].instagram),
          youtube: Number(response.body[0].youtube),
          twitch: Number(response.body[0].twitch),
          loaded: false
        }
        commit('SET_METRICS', out)
        resolve(out)
      }).catch((e) => {
        console.log(e)
      })
    })
  }

В приведенном выше примере я отправляю экземпляр текущего store.state.metrics.loaded когда отправляется событие отправки. Затем проверяется, чтобы увидеть истинность текущего значения. Поскольку первая загрузка всегда должна возвращать false, мы возвращаем обещание, используя вызов API, а также мутируем хранилище, поэтому у нас есть значения из более позднего. Таким образом, поскольку мы мутировали загруженное событие как истину, следующие дополнительные экземпляры должны возвращать значение true, и новое обещание будет разрешено, чтобы мы могли убедиться, что обработчик .then() присутствует.

Составная часть

created: function () {
      this.$store.dispatch('LOAD_METRICS', this.$store.state.metrics.loaded).then((res) => {
        if (res !== 'loaded') {
          this.updateNumbers(res)
        } else {
          this.socialIcons[0].count = this.kFormatter(this.$store.state.metrics.twitter) + 'K'
          this.socialIcons[1].count = this.kFormatter(this.$store.state.metrics.instagram) + 'K'
          this.socialIcons[2].count = this.kFormatter(this.$store.state.metrics.youtube) + 'K'
          this.socialIcons[3].count = this.kFormatter(this.$store.state.metrics.twitch) + 'K'
        }
      })
    }

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

Я считаю, что существует более эффективный метод подхода, а затем рассмотрение логики состояния в среде действия и возвращение обещания, которое является по существу избыточным, кроме обеспечения .then().

Ещё вопросы

Сообщество Overcoder
Наверх
Меню