Как отобразить загруженные данные после обновления страницы в 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.
Извините за длинный пост.