Vuex сбрасывает уже установленные состояния

#vue.js #vuex #vue-router #state-management

#vue.js #vuex #vue-маршрутизатор #управление состоянием

Вопрос:

Начал играть с Vuex и немного запутался.

Он запускает действие GET_RECRUITERS каждый раз, когда я загружаю компонент company.vue , тем самым также вызывая api-вызов.

Например, если я открою company.vue => перейдите к user/edit.vue with vue-router и они вернутся, он снова вызовет действие / api (рекрутеры сохраняются в хранилище в соответствии с Vue-dev-tools).

Пожалуйста, поправьте меня, если я ошибаюсь — он не должен запускать действие / api и, таким образом, сбрасывать состояние, если я снова вернусь на страницу, правильно? Или я неправильно понял намерение Vuex?

company.vue

 <template>
  <card>

    <select>
      <option v-for="recruiter in recruiters"
              :value="recruiter.id">
        {{ recruiter.name }}
      </option>
    </select>

  </card>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  middleware: 'auth',

  mounted() {
    this.$store.dispatch("company/GET_RECRUITERS")
  },

  computed: mapGetters({
    recruiters: 'company/recruiters'
  }),

}
</script>
 

company.js

 import axios from 'axios'

// state
export const state = {
  recruiters: [],
}

// getters
export const getters = {
  recruiters: state => { 
    return state.recruiters
  }
}

// actions
export const actions = {
  GET_RECRUITERS(context) {

    axios.get("api/recruiters")
      .then((response) => {
        console.log('API Action GET_RECRUITERS')
        context.commit("GET_RECRUITERS", response.data.data) 
      })
      .catch(() => { console.log("Error........") })
  }

}

// mutations
export const mutations = {
  GET_RECRUITERS(state, data) {
    return state.recruiters = data
  }
}
 

Спасибо!

Комментарии:

1. У вас есть запрос внутри mounted перехвата, поэтому он будет вызываться каждый раз при монтировании компонента. Вместо этого попробуйте использовать его в created перехватчике

Ответ №1:

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

  • Загрузите данные в App.vue, который запускается только один раз.
  • Или проверьте, что данные еще не загружены, прежде чем выполнять вызов API:
 // Testing that your `recruiters` getter has no length before loading data
mounted() {
   if(!this.recruiters.length) {
      this.$store.dispatch("company/GET_RECRUITERS");
   }
}
 
  • Или кэшируйте компонент страницы, чтобы он не создавался заново каждый раз, когда вы отправляетесь обратно. Сделайте это, используя <keep-alive> компонент для переноса <router-view> :
 <keep-alive>
   <router-view :key="$route.fullPath"></router-view>
</keep-alive>