У меня есть приложение vue, использующее vex для хранения данных всего сайта, я получаю информацию о пользователе и помещаю ее в состояние перед созданием метода жизненного цикла следующим образом:
const app = new Vue({
el: '#app',
store,
beforeCreate(){
store.dispatch('currentUser');
}
});
В моем пользовательском модуле у меня есть геттер, который получает имя пользователя, как показано ниже:
const getters = {
getName(state){
return state.user.name;
}
};
В своих компонентах я пытаюсь получить доступ к получателю, чтобы отобразить имя пользователя в компоненте. Когда я смотрю на инструменты разработчика Vue Chrome, получатель не является неопределенным, но когда я консоль записываю результаты получателя, например, он говорит undefined.
mounted(){
console.info(store.getters.getName);
},
Кажется, что компонент загружается до загрузки состояния. Я получаю информацию о пользователе с помощью axios. Я действительно не понимаю, как решить эту проблему, поскольку я не могу вызвать действие для получения пользовательских данных раньше, чем я знаю.
Если в моем методе получения я делаю:
state.user
Я получаю это:
{ "id": 1, "name": "Test" }
Но когда я пытаюсь получить имя, я получаю неопределенное
Вот магазин:
import axios from "axios/index";
const state = {
user: {},
};
const mutations = {
FETCH_USER(state,user){
state.user = user;
},
UPDATE_AVATAR(state,avatar){
state.user.avatar = avatar;
}
};
const getters = {
getName(state){
return state.user.name
},
avatar(state){
return state.user.avatar;
},
userSocialNetworks(state){
//return state.user.social_networks
},
schoolName(state){
return state.user.school
},
schoolAbout(state){
return state.user.school.about
},
schoolAddress(state){
return state.user.school.address
}
};
const actions = {
currentUser: ({commit}) => {
axios.get('/api/user').then(response => {
commit('FETCH_USER', response.data);
});
}
}
export default {
state,
getters,
actions,
mutations
}
{"user":{"user":{"name":"Test","email":"[email protected]","avatar":"http://www.gravatar.com/avatar/xxxx=300","city":null,"state":null,"zip":null,"address":null,"lat":null,"long":null,"role":"school","school":{"id":1,"about":null,"header":null,"name":"Test","user_id":1,"created_at":"2018-06-06 19:48:16","updated_at":"2018-06-06 19:48:16"},"following":[],"followers":[],"social_networks":[{"id":4,"user_id":1,"social_network_id":1,"network_url":"test.com/k","created_at":"2018-06-06 23:11:09","updated_at":"2018-06-06 23:15:19"},{"id":5,"user_id":1,"social_network_id":2,"network_url":"test.com/k","created_at":"2018-06-06 23:15:19","updated_at":"2018-06-06 23:15:19"},{"id":6,"user_id":1,"social_network_id":5,"network_url":"test.com/k","created_at":"2018-06-06 23:16:15","updated_at":"2018-06-06 23:16:15"}]}},"socialNetowrks":{"available_networks":[{"id":1,"network_name":"Facebook","created_at":null,"updated_at":null},{"id":2,"network_name":"Instagram","created_at":null,"updated_at":null},{"id":5,"network_name":"Twitter","created_at":null,"updated_at":null}]}}
В чем разница
Разница в том, что одно не определено, а другое - нет.
@Derek Я получаю эту ошибку, используя хранилище таким образом. Ошибка в смонтированном хуке: «TypeError: не удается прочитать свойство 'name' of undefined»
Это означает, что state.user не определен.
@Derek, когда я просто выполняю state.user, он возвращает {"id": 1, "name": "Test"}, но name делает его неопределенным
У вас Vue.use(vuex)?
@ Дерек, да, я это сделал. Я могу вернуть объект, который содержит имя в порядке, без ошибок, но когда я пытаюсь получить от него имя, это когда он дает мне ошибки
Этот тип ошибки указывает на то, что vue.use(vuex); не выполняется. Что отображается на вкладке Vue DevTools Vuex?
@Derek Отображает весь пользовательский объект с его именем и связями
Покажи мне, как выглядит твой магазин, отредактируйте исходный пост
@Derek Это в вопросе
Я имел в виду код магазина, а не данные о состоянии магазина.
@Derek - в вопросе пользовательский модуль
Как вы экспортируете / импортируете свой магазин? это должно быть что-то вроде export default new Vuex.Store({}); и import store from './store'
@Derek Я импортирую его, как и у вас, и все модули импортируются в файл index.js в каталоге магазина. В индексном файле я использую этот экспорт по умолчанию new Vuex.Store
Попробуйте использовать mounted() вместо beforeCreate()
@Derek Я перепробовал весь метод жизненного цикла, и та же ошибка сохраняется.
У меня точно такая же проблема, вы когда-нибудь находили решение?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Во-первых, в хуке beforeCreate методы еще не инициализированы. Самый простой способ обойти это - использовать вместо этого хук created:
const app = new Vue({
el: '#app',
store,
created(){
store.dispatch('currentUser'); // considering you have properly imported and exported vuex
}
});
В вашем компоненте
import {mapGetters} from 'vuex';
export default {
computed: {
...mapGetters(['getName'])
}
}
Даже это не работает. Метод schoolName может возвращать объект, но не атрибут name.
Вы можете попробовать это:
mounted() {
setTimeout(() => {
console.info(store.getters.getName);
}, 400);
},
Попробуйте объявить конкретные переменные в магазине, чтобы правильно инициализировать данные:
const state = {
user: {
name: '',
avatar: '',
school: '',
...
},
};
У меня была та же проблема, которую вы описали, пока я не сделал это.
Здесь вы столкнулись с двумя большими проблемами:
Поэтому убедитесь, что вы правильно объявляете все свое состояние и назначаете объекты вместо их перезаписи.
import assignDeep from 'assign-deep'; //Since you have nested structure you will need this
const state = {
user: {
name: '',
school: {
about: '',
address: '',
},
// Make sure all properties are defined
},
};
const mutations = {
FETCH_USER(state,user){
assignDeep(state.user, user);
},
UPDATE_AVATAR(state,avatar){
state.user.avatar = avatar;
}
};
Сначала воспользуйтесь утилитой mapGetters vuex для упрощения использования.
import { mapGetters } from 'vuex';
//... In component definition
computed: {
...mapGetters({name: 'getName'})
}
Поскольку это вычисляемое свойство vue, ваш компонент будет повторно визуализироваться, когда он будет определен, и все должно отображаться правильно, вам просто нужно убедиться, что вы обрабатываете случай, когда он пуст, и, возможно, отображаете экран загрузки, пока он не будет
Например
<template>
<div v-if = "!name" class = "loading"></div>
<div v-else>{{name}}</div>
<template>
Вы также можете просто дождаться обновления собственности.
Не используйте его в смонтированном хуке, так как там оно все равно будет значением по умолчанию.
Вместо этого используйте наблюдатель или вычисляемое свойство в зависимости от ваших потребностей
watch: {
name: {
handler(name, oldName) {
if (name) {
//Do something
}
},
immediate: true
}
}
вам нужно использовать
this.$store.getters.getNameв компонентах