簡體   English   中英

Vuex getter 返回未定義

[英]Vuex getter returns undefined

我有一個使用 vex 存儲站點范圍數據的 vue 應用程序,我獲取用戶信息並將其置於創建生命周期方法之前的狀態,如下所示:

const app = new Vue({
    el: '#app',
    store,
    beforeCreate(){
        store.dispatch('currentUser');
    }
});

在我的用戶模塊中,我有一個獲取用戶名稱的 getter,如下所示:

const getters = {
    getName(state){
        return state.user.name;
    }
};

在我的組件中,我試圖訪問 getter 以在組件中顯示用戶的名稱。 當我查看 Vue Chrome 開發工具時,getter 不是未定義的,但是當我控制台記錄 getter 結果時,它顯示為未定義。

mounted(){
    console.log(store.getters.getName);
},

似乎組件在加載狀態之前正在加載。 我正在使用 axios 獲取用戶信息。 我真的很困惑如何解決這個問題,因為我無法盡快調用該操作來獲取用戶數據。

如果在我的 getter 方法中我這樣做:

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":"test@test.edu","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}]}}

您在這里面臨兩個大問題:

  1. 您不應該直接在 vuex 存儲中更新對象,否則您將失去反應性

因此,請確保正確聲明所有狀態並分配給對象而不是覆蓋它們

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;
    }
};
  1. 您正在嘗試訪問在狀態上異步定義的屬性並同步使用它(在它存在之前)

首先使用 vuex 的mapGetters實用程序,以便於使用

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
  }
}

首先,在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'])
  }
}

嘗試在 store 中聲明特定變量以正確初始化數據:

const state = {
    user: {
        name: '',
        avatar: '',
        school: '',
        ...
    },
};

在我這樣做之前,我遇到了與您描述的相同的問題。

你可以試試這個:

mounted() {
  setTimeout(() => {
    console.log(store.getters.getName);
  }, 400);
},

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM