IT이야기

Vuex에서 정의되지 않은 속성 'displatch'를 읽을 수 없음

cyworld 2022. 3. 7. 21:33
반응형

Vuex에서 정의되지 않은 속성 'displatch'를 읽을 수 없음

vuex 스토어에 있는 'logOutUser'에서 디스패치를 수행하려고 하는데 다시 연기할 때 다음 오류 메시지가 표시됨:

TypeError: 정의되지 않은 속성 'dispatch'를 읽을 수 없음

deleteUser.vue(파견 작업이 작동하지 않는 구성 요소):

<template>
    <v-dialog v-model="openDelete" persistent max-width="500px">
        <v-card>
            <v-card-title>
                <h4>Delete User</h4>
            </v-card-title> 
            <v-card-text>
                <h2>Are You Sure?</h2>
                <p>Deleting your user is a permanent action.</p>
                <br>
                <br>
                <v-btn
                 color="primary"
                 @click="deleteUser">
                 Delete User
                </v-btn>
                <v-btn
                 color="primary"
                 @click="openDelete = false">
                 Close
                </v-btn>  
            </v-card-text>  
        </v-card>   
    </v-dialog> 
</template>
<script>
import router from '../../router/index.js'
const firebase = require('../../firebaseConfig.js')
export default {
    data: function(){
        return {
            openDelete: true
        }
    },
    methods: {
        deleteUser: function(){
            let user = firebase.auth.currentUser
            const docId = user.uid
            console.log("Trying to delete user ", docId)
            user.delete().then(function() {
            }).catch(function(error) {
                console.error("Error deleting user: ", error)
            });
            firebase.firestore.collection("users").doc(docId).delete().then(() => {
                        console.log('Trying to Log Out in Vuex')
                        this.$store.dispatch('user/logOutUser')
                        alert("User Deleted Successfully!")
                }).catch(function(error) {
                    console.error("Error removing document: ", error);
                });
            router.push('hello')    
            this.openDelete = false
        }
    }
}
</script>

store.js:

import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import genre from './modules/genre'

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        user,
        genre
    }
})

user.js:

const firebase=require('../firebaseConfig.js')

const state = {
    currentUser: null,
    userProfile: {}
}

const actions = {
        fetchUserProfile({commit, state}, uid){
            firebase.firestore.collection("users").doc(uid).get().then((doc)=>{
                commit('setUserProfile', doc.data())
            }).catch((error)=>{
                console.error(error)
            })
        },
        logOutUser({commit, state}){
            commit('setCurrentUser', null)
            commit('setUserProfile', {})
            console.log('Logged Out In Vuex')
        }
}

const mutations = 
    {
        setCurrentUser(state, val){
            state.currentUser = val
        },
        setUserProfile(state, val){
            state.userProfile = val
        }
    }

export default {
    namespaced: true,
    state,
    actions,
    mutations
}   

편집: main.js 파일:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store.js'
const firebase = require('./firebaseConfig.js')

Vue.config.productionTip = false

let app

firebase.auth.onAuthStateChanged(user => {
  if(!app){
    /* eslint-disable no-new */
    app = new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
  }
});

내 어플리케이션의 다른 컴포넌트로부터 이 액션을 전송한다고 말해야겠어.거기서부터 완벽하게 작동해.

고마워!

그건 아마 네가 추가하지 않았기 때문이야.storeVue의 루트 인스턴스에 대한 옵션.그것을 제공함으로써 당신은 루트의 모든 자식 구성 요소로부터 상점에 접근할 수 있을 것이다.따라서 루트 인스턴스는 다음과 같이 표시되어야 한다.

import store from './store'

const app = new Vue({
  /* .. other properties .. */
  store
})

이제 자유롭게 사용할 수 있다.this.$store구성 요소 내에서

왜 정의되지 않는지, 모듈을 사용할 때 왜 작동하는지 불명확하지만 모듈이 없으면 안 된다.빌드 프로세스/트랜스필러와 관련이 있을 수 있다.만약use사실 의 정적 방법이다.Vue그럼, 수업시간$store플러그인을 설치하여 모든 인스턴스에서 공유됨use, 그러나 이것은 사실이 아니다.처럼 보인다.VueVue 모듈이 내보낸 클래스여야 하지만 인스턴스처럼 동작하는 것 같다.

내가 일하는 것을 알게 된 것은 다음 중 하나(선호하는 것 #3)이다.

1.콜Vue.useVuex가 사용되는 모든 곳

src
├── App.vue
├── main.js <- Vue.use(Vuex)
├── router 
│   └── index.js <- Vue.use(Vuex)
└── store
    ├── myModule.js
    └── index.js <- Vue.use(Vuex)
// store/index.js
import Vue from "vue"; // This module's Vue is not the same instance as that referenced in main.js
import Vuex from "vuex";
import myModule from "./myModule.js";

// Required before creating new store instance
Vue.use(Vuex);

export const store = new Vuex.Store(myModule);
// main.js
import Vue from "vue"; // this module's Vue is different from store/index.js' Vue
import Vuex from "vuex";
import app from "./App";
import router from "./router/index.js";
import { store } from "./store/index.js";

// this part is essential despite already calling Vue.use in store/index.js
Vue.use(Vuex);
// Or, see alternative below

new Vue({
    ...,
    router,
    store,
    components: { app }
});

2. 세트$store의 모든 경우에 있어서Vue

(유카시마후크세이가 지적한 바와 같이)

src
├── App.vue
├── main.js <- Vue.prototype.$store = store
├── router 
│   └── index.js
└── store
    ├── myModule.js
    └── index.js
Vue.prototype.$store = store;

3. 글로벌 수입Vue상점과 본점에 예시하다.

src
├── App.vue
├── global.js
├── main.js <- Vue.use(Vuex)
├── router
│   └── index.js
└── store
    ├── myModule.js
    └── index.js
// global.js
import vue from "vue";
export const Vue = vue;

// or if you're not using babel, you can use real javascript…,
export { Vue } from "vue";
// store/index.js
import { Vue } from "../global.js";
import vuex from "vuex";
import myModule from "./myModule.js";

Vue.use(vuex);

export const store = new vuex.Store(myModule);
// main.js
import { Vue } from "./global.js";
import store from "./store/index.js";
import router from "./router/index.js";
import app from "./App";

new Vue({
    ...,
    router,
    store,
    components: { app }
});

그래서 나는 너의 모든 해결책을 시도해봤지만, 나에게는 아무 것도 효과가 없는 것 같아.나는 그 문제가 deleteUser와 관련이 있다고 의심하기 시작했다.vue는 App.vue의 직접 자녀가 아니다.내가 한 사람은 결국 매장을 구성 요소로 직접 수입했다.

import store from '../../store.js'

그것으로 문제가 해결되었다.이 문제를 해결하는 더 효율적인 방법을 아는 사람이 있는지 궁금하다.도와줘서 고마워!

이렇게 하다

그대로 두어라.

그걸 이용해서 파견을 하는 겁니다

that.$store.properties(액션)

다른 쪽에서는

firebase.auth.onAuthStateChanged(user => {
  if(!app){
    /* eslint-disable no-new */
    app = new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })
  }
});

나도 그런 상황이었기 때문에 이 코드 조각이 있을 거라고 장담하지만, 매번 모든 것을 다시 렌더링할 것이기 때문에 페이지 리로드에서 당신의 어플리케이션을 훨씬 더 느리게 만들 것이다.

라우터에서 OnAuthStateChanged Event(예: 가능한 경우)를 사용한 후 가능한 경로 블록 여부를 확인하십시오.

나는 코드 예시를 위해 집에 있는 것은 아니지만 네가 원한다면 오늘 늦게 보낼 수 있어.

스토어를 초기화하지 않았거나 잘못되었을 것으로 추측함this문맥의

디버깅을 위해 나는 사용하려고 한다.mapActions도우미 vuex.vuejs.org:

import { mapActions } from 'vuex'

export default {
  methods: {
    ...mapActions({
      add: 'increment' // map `this.add()` to `this.$store.dispatch('increment')`
    })

    // ...
  }

  // ...
}

만약 우리가 vueX가 제안한 앱 구조를 따를 거라면.

스토어가 자동으로 주입됨

https://vuex.vuejs.org/guide/structure.html

나도 같은 문제가 있었어, 심지어 나만의 Stackoverflow 질문을 했는데, 결국 내가 직접 여기에 올린 해결책을 찾을 때까지 소용이 없었어.

게시된 답변의 내용은 다음과 같다.

나는 마침내 해결책을 찾을 때까지 이틀 동안 이 문제와 씨름하고 있었다.

내 문제는 내가 사용했기 때문이다.$navigateTo프레임을 지정하지 않고, 나는 전체 구성요소를 탐색하고 있었다.나는 main.js에서 렌더 함수에 전달되는 첫 번째 구성 요소에만 스토어가 바인딩되어 있다는 것을 발견했다.

내 main.js는 다음과 같이 보였다.

new Vue({
  store,
  render: h => h('frame', [h(store.state.is_logged_in ? Main : Login)]),
  created() {
    this.$store.commit('setNav', this.$navigateTo);
    if (this.$store.state.is_logged_in) {
      this.$store.dispatch('init');
    }
  },
}).$start();

이라면 if is_logged_ini true 인데, If is_logged_ini true 인데, if is_logged_ini true 인데, If isthis.$store또는mapActions에만 효과가 있었다.Main 아동의 야.Login아동 구성품이야그때 나는 이것을 읽고 있다가 다음 코드를 보았다.store예시 코드:

import Vue from 'nativescript-vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({...});
Vue.prototype.$store = store;
module.exports = store;

그래서 선을 더했다.Vue.prototype.$store = store;나의 가게 정의에 따라 마침내 나의 문제가 해결되었다.이것은 정말 나를 힘들게 했다.내가 누군가를 구할 수 있기를 바래.

나도 이 문제가 있었는데 알고 보니 이름이 소문난 대신 수도로 부에와 부에를 수입해 왔다.이게 제대로 수입하는 방법이지만 이것이 가능한 문제라는 것을 알려주는 오류가 없기 때문에 적발하기가 매우 어렵다.나는 그것이 자본이 되어서는 안 된다는 것을 알지만, 누구나 오타를 할 수 있고 이것이 문제라는 징후는 없다.

내가 가지고 있던 것은 다음과 같다: (그러니까 이 코드를 복사하지 마, 작동하지 않을 거야)

import Vue from 'Vue';
import Vuex from 'Vuex';

올바른 방법:

import Vue from 'vue';
import Vuex from 'vuex'; //<-- not Sentence case from '[V]uex' but '[v]uex'

그런 바보 같은 실수였지만, 다른 사람들도 같은 문제를 겪었을 텐데, 이게 도움이 되었으면 좋겠다.

나는 "점포"를 수입하지 못했기 때문에 같은 문제에 직면했다.다음과 같이 해결됨:

import store from './store'

new Vue({
  el: '#app',
  store,
  render: h => h(App),
})

참조URL: https://stackoverflow.com/questions/52482814/cannot-read-property-dispatch-of-undefined-in-vuex

반응형