Vuex: возвратный геттер в установленном крюке - PullRequest
0 голосов
/ 08 июля 2019

В моем App.vue Я отправляю действие Vuex для получения user из моего API, а также role пользователя следующим образом:

async mounted() {
    const userToken = localStorage.getItem('token');
    await this.getUserRole(userToken);
    await this.getUserImage(userToken);
  },

Я написал метод получения, который возвращает мне только текущую роль, которая сохранена в пользовательском объекте, как этот getRole: state => state.user_role.role

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

async mounted() {
    console.log(this.$store.getters['user/getRole']);
    console.log(this.userRole);

    if (this.userRole === 'user') {
      // do things ...
    }
}
computed: {
    ...mapGetters('user', {
      user: 'getUser',
      userRole: 'getRole',
    })
}

Проблема здесь в том, что при первой загрузке / обновлении страницы я получаю undefined от моего геттера. Только если я переключаю маршрут и возвращаюсь, он возвращает меня в этом случае user вместо undefined.

Я имею в виду, что я мог бы снова отправить действие user/getUserRole в моем Project.vue, но я думаю, это было бы плохо, так как у меня есть несколько вызовов для одного и того же магазина / действия.

Я также пытался работать с $nextTick() в моем mounted(), но это также не помогло.

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Просмотр вычисленного и выполнение кода после установки роли пользователя, например:

computed: {
    ...mapGetters('user', {
      user: 'getUser',
      userRole: 'getRole',
    })
},

watch: {
    userRole: {
        handler(role) {
             if (role) {
                 this.yourAction();
             }
        },
        immediate: true
    }
},

methods: {
    yourAction() {
        console.log('got role:', this.userRole);
    }
}

Свойство immediate используется в наблюдателе для userRole, поэтому обработчик будет вызываться сразу после загрузки компонента.

1 голос
/ 08 июля 2019

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

В состояниях вашего магазина вы можете определить какой-то набор, который содержит логические свойства.

api_calls_ok: {
    user_data: false
}

Затем вы можете определить действие, аналогичное этому.

const userToken = localStorage.getItem('token'); //side note: you can use localStorage.token instead
await this.getUserRole(userToken);
await this.getUserImage(userToken);

Возможно, что-то вроде

getUserData({ commit, state }){
    if(!state.api_calls_ok.user_data){
        dispatch('getUserRole');
        dispatch('getUserImage');
        commit('flagApiCalls', 'user_data', true); //set the boolean to true
    }
}

В App.vue и Project.vue вы можете просто отправить getUserData во время монтирования и не беспокоиться о вызове API дважды или более,После отправки просто получите доступ к своему получателю.

...