source

vuex에서 마운트된 함수의 저장소 데이터에 액세스하는 방법

factcode 2022. 9. 28. 00:04
반응형

vuex에서 마운트된 함수의 저장소 데이터에 액세스하는 방법

1개의 루트 컴포넌트를 사용하고 있습니다.App.vue기타 컴포넌트는 다음과 같습니다.FileUploaderParent.vue·데이터를 스토어에 저장하겠다는 디스패치 약속으로 전화드렸습니다.마운트된 라이프 사이클 훅으로 디스패치를 호출합니다.

한편, 다른 컴포넌트에 탑재된 기능으로 저장된 사용자 데이터에 액세스하려고 합니다.정의되지 않은 오류를 보여줍니다.

네, 마운트된 함수에 대해 동일한 디스패치 약속을 호출하는 작업이 가능합니다.하지만 해킹처럼 느껴지고 디스패치 콜도 점점 중복되고 있습니다.

여기 코드가 있습니다.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
        }
}

에러는 다음과 같습니다.

에서 스토어 데이터에 액세스하려면FileUploaderParent.vue탑재된 기능 중입니까?

작성한 코드는 맞는 것 같습니다만, 아직 답변이 필요하시면 매장에서 시계를 이용하실 수 있습니다.

this.$store.watch(() => this.$store.state.userData, async () => {
 //do your code here 
});

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

this.$store.gettersVuex 스토어의 getter를 나타냅니다.Vuex 스토어에는 getter가 없습니다.최소한 샘플에는 아무것도 표시되지 않습니다.(https://vuex.vuejs.org/guide/getters.html)

언급URL : https://stackoverflow.com/questions/56765791/how-to-access-store-data-in-mounted-function-in-vuex

반응형