Как получить доступ к данным магазина в смонтированной функции в vuex - PullRequest
0 голосов
/ 26 июня 2019

У меня есть один корневой компонент, известный как App.vue.и другой компонент с именем FileUploaderParent.vue.Я звоню в посылочное обещание хранить данные в магазине.Я вызываю диспетчеризацию при подключенном подключении жизненного цикла.

С другой стороны, я пытаюсь получить доступ к сохраненным пользовательским данным в смонтированной функции другого компонента.Он показывает ошибку undefined

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

Вот код для App.vue:

<template>
  <v-app>
    <v-navigation-drawer  v-model="drawer" app temporary >
      <v-img :aspect-ratio="16/9" src="https://image.freepik.com/free-vector/spot-light-background_1284-4685.jpg">
        <v-layout pa-2 column fill-height class="lightbox gray--text">
          <v-spacer></v-spacer>
          <v-flex shrink>
            <!-- <div class="subheading">{{this.$store.getters.userData.name}}</div> -->
            <!-- <div class="body-1">{{this.$store.getters.userData.email}}</div> -->
          </v-flex>
        </v-layout>
      </v-img>
      <v-list>
        <template v-for="(item, index) in items">
          <v-list-tile :href="item.href" :to="{name: item.href}" :key="index">
            <v-list-tile-action>
              <v-icon light v-html="item.icon"></v-icon>                
            </v-list-tile-action>
            <v-list-tile-content>
              <v-list-tile-title v-html="item.title"></v-list-tile-title>
            </v-list-tile-content>
          </v-list-tile>
        </template>
      </v-list>
    </v-navigation-drawer>
    <v-toolbar color="white" light :fixed=true>
      <v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
      <v-img :src="require('@/assets/mad_logo.png')" max-width="80px" max-height="41px"  />     
      <v-toolbar-title class="black--text justify-center" > <h1>MeshApp</h1></v-toolbar-title>
      <v-spacer></v-spacer>
      <v-avatar color="primary">
        <!-- <span class="white--text headline">{{this.avatar.slice(0,2)}}</span>          -->
      </v-avatar>   
    </v-toolbar>
    <v-content style="margin-top: 60px;">
      <v-fade-transition mode="out-in">
        <router-view></router-view>
      </v-fade-transition>
    </v-content>
  </v-app>  
</template>

<script>
export default {
  name: 'app',
  components: {

  },
  data() {
    return {   
      avatar: '',    
      drawer: false,
      items: [
        {
          href: 'home',
          router: true,
          title: 'home',
          icon: 'grid_on',
        },
        {
          href: 'view_volunteers',
          router: true,
          title: 'View Volunteer',
          icon: 'group'
        },
        {
          href: 'profile',
          router: true,
          title: 'profile',
          icon: 'account_circle',
        }, 
        {
          href: 'logout',
          router: true,
          title: 'Logout',
          icon: 'toggle_off',
        }

      ]
    }
  },
  props: [], 
  mounted() {
   this.$store.dispatch('getUserData').
    then(() => {      
     let findAvatar = this.$store.getters.userData.name.split(" ")
     let createAvatar = ''
     for(let i = 0; i < findAvatar.length; i++) {
       createAvatar = createAvatar + findAvatar[i].slice(0,1)
     }
     this.avatar = createAvatar
     console.log(this.avatar)
     // this.$store.dispatch('getUserId', id) 
   })    
  }   
}

</script>

<style scoped>

v-content {
  margin-top: 60px !important;
}
</style>

Вот код для FileUploaderParent.vue:

<template>
  <v-layout class="text-xs-center ">
    <v-flex>
      <image-input v-model="avatar">
        <div slot="activator">
          <v-avatar color = "primary" size="150px" v-ripple v-if="!avatar" class=" mb-3">
            <h1 class="white--text"><span>{{this.defaultAvatar}}</span></h1>
          </v-avatar>
          <v-avatar size="150px" v-ripple v-else class="mb-3">
            <img :src="avatar.imageURL" alt="avatar">
          </v-avatar>
        </div>
      </image-input>
      <v-slide-x-transition>
        <div v-if="avatar && saved == false">
          <!-- Stores the Image and changes the loader -->
          <v-btn  class="primary" @click="uploadImage" :loading="saving">Save Avatar</v-btn>
        </div>
      </v-slide-x-transition>
    </v-flex>
  </v-layout>
</template>

<script>
import ImageInput from './FileUploaderChild.vue'

export default {
  name: 'app',
  data () {
    return {
      defaultAvatar: '',
      avatar: null,
      saving: false,
      saved: false
    }
  },
  mounted() {
     this.$store.dispatch('getUserData').
    then(() => {
      let findAvatar = this.$store.getters.userData.name.split(" ")
      let createAvatar = ''
      for(let i = 0; i < findAvatar.length; i++) {
        createAvatar = createAvatar + findAvatar[i].slice(0,1)
      }
      this.defaultAvatar = createAvatar
    })
  },
  components: {
    ImageInput: ImageInput
  },
  watch:{
    avatar: {
      handler: function() {
        this.saved = false
      },
      deep: true
    }
  },
  methods: {
    uploadImage() {
      this.saving = true
      setTimeout(() => this.savedAvatar(), 1000)
    },
    savedAvatar() {
      this.saving = false
      this.saved = true
    }
  }
}
</script>

<style>

</style>

Вот так выглядит магазин:store.js

actions: {
        getUserData(context)  {
            return new Promise((resolve, reject) => {
                axios.get('http://someurl.in/api/v1/users/'+this.state.userId, {
                    headers: {
                        'Content-Type': 'application/json'               
                    },
                    auth: {
                        username: 'someusername',
                        password: 'pass'
                    }    
                }).
                then(response => {
                    context.commit('storeUserData', response.data.data.users)                    
                    resolve(response);  // Let the calling function know that http is done. You may send some data back
                }).catch(error => {
                    reject(error);
                })        
            })
        }
},
mutations: {
        storeUserData(state, data) {
            state.userData = data
        }
}

Вот как выглядит ошибка: enter image description here

Как получить доступ к данным хранилища в FileUploaderParent.vue при смонтированной функции?

Ответы [ 3 ]

0 голосов
/ 26 июня 2019

this.$store.getters относится к получателю в вашем магазине Vuex. У вас нет добытчиков в вашем магазине Vuex - по крайней мере, их нет в вашем образце. (https://vuex.vuejs.org/guide/getters.html)

0 голосов
/ 28 июня 2019

Код, который вы написали, кажется правильным, но если вам все еще нужен ответ, вы можете использовать часы в магазине

this.$store.watch(() => this.$store.state.userData, async () => {
 //do your code here 
});
0 голосов
/ 26 июня 2019

Как насчет добавления проверки, которая определяет, требуется ли вызов API:

actions: {
  getUserData(context) {
    return new Promise((resolve, reject) => {
      // Be sure to set the default value to `undefined` under the `state` object.
      if (typeof this.state.userData === 'undefined') {
        axios
          .get('http://someurl.in/api/v1/users/' + this.state.userId, {
            headers: {
              'Content-Type': 'application/json'
            },
            auth: {
              username: 'someusername',
              password: 'pass'
            }
          })
          .then(response => {
            context.commit('storeUserData', response.data.data.users);
            resolve(response.data.data.users);
          })
          .catch(error => {
            reject(error);
          });
      }
      else {
        resolve(this.state.userData);
      }
    })
  }
}
...