Как отобразить загруженные данные после обновления страницы в vue?

У меня есть компонент с некоторыми элементами, и эти элементы загружаются из API с помощью get request метод. Когда я нажимаю на элемент, я перенаправляюсь на его собственную страницу, используя динамическую маршрутизацию: { path: '/:id', component: Item }, Выбранный элемент распознается с помощью currentItem() метод: currentItem() { this.items.find(item => item.code === this.$route.params.id) } где item.code это свойство, которое я получаю от API. Моя проблема в том, что когда я обновляю страницу текущим элементом, она больше не загружается. Я пытался с помощью beforeCreate() загрузить элементы еще раз в их собственный компонент. Может быть, я мог бы использовать watch изменить состояние в зависимости от предмета?

beforeCreate() {
    this.$http.get(url).then(response => {
          this.items = response.body;
    }
},
watch: {
    '$route' (to, from) {
      this.currentItem()
    }
  }

Вот демо.

1 ответ

Решение

Вы должны добавить watch за $route реагировать на id меняется при переходе между страницами. Но в этом случае есть шанс, что currentItem верните ноль, потому что ваш запрос будет завершен после того, как обработчик наблюдения уже будет вызван.

Первое решение - смотреть items коллекция в Item компонент и вызвать this.currentItem() в этом обработчике часов. И да, вам придется загрузить items в вашем Item компонент, как в вашем примере.

Вторым является использование computed имущество currentItem вместо метода, если это возможно:

computed: {
   currentItem() {
       return this.items.find(item => item.code === this.$route.params.id)
   }
}

Это будет реактивным, и вам больше не нужно смотреть. Но не забудьте сделать this.items пустой массив по умолчанию, чтобы избежать ошибок NULL.

Третье решение - это комбинация второго с использованием магазина Vuex, чтобы разделить коллекцию элементов между всеми компонентами и сделать что-то вроде этого:

beforeCreate() {
    // you should check in this action that items already loaded earlier as well
    this.$store.dispatch('loadItems');
},
computed: {
   currentItem() {
       return this.items.find(item => item.code === this.$route.params.id)
   },
   items() {
       return this.$store.state.items
   }
}

Хранить:

state: {
   items: [],
   itemsLoaded: false,
}
actions: {
   loadItems({state, commit}) {
      // avoid unnecessary loading between navigations
      if (itemsLoaded) return
      Vue.http.get('some url').then(response => {
          commit('setItems', response.body);
          commit('itemsLoaded');
      }
   }
},
mutations: {
   setItems: (state, items) => state.items = items 
   itemsLoaded: (state) => state.itemsLoaded = true
}

Так что вам не нужно хранить элементы, например, в компонентах Item и Items.

Извините за длинный пост.

Другие вопросы по тегам