简体   繁体   中英

Vue: TypeError: Cannot read property 'dispatch' of undefined when submitting login form

I'm getting the TypeError: Cannot read property 'dispatch' of undefined error when I'm trying to submit the Login.vue form. I changed my function() to just data() etc, like SO answers suggested, but it didn't help...

index.js :

import Vue from 'vue';
import Vuex from 'vuex';

import auth from './store/auth.module.js';

Vue.use(Vuex);

export default new Vuex.Store({
    //plugins: [createPersistedState({ storage: sessionStorage })],
    state: {  },
    mutations: {  },
    actions: {  },
    modules: { auth }
})

main.js :

import Vue from 'vue'
import App from './App.vue'
import router from './router';
import store from './store/auth.module';
import "./assets/css/tailwind.css";
import '@/assets/css/tailwind.css';

Vue.config.productionTip = false;

new Vue({
  router, 
  store,
  render: h => h(App),
}).$mount('#app');

auth-header.js :

export default function authHeader() {
    let user = JSON.parse(localStorage.getItem('user'));

    if (user && user.accessToken) {
        return { Authorization: 'Bearer ' + user.accessToken };
    } else {
        return {};
    }
}

user.service.js :

import axios from 'axios';
import authHeader from './auth-header';

const API_URL = 'localhost:8088/testproject/api/users';

class UserService {
    getPublicContent() {
        return axios.get(API_URL + '/all');
    }

    getUserBoard() {
        return axios.get(API_URL + '?role=user', { headers: authHeader() });
    }

    getModeratorBoard() {
        return axios.get(API_URL + '?role=mod', { headers: authHeader() });
    }

    getAdminBoard() {
        return axios.get(API_URL + '?role=admin', { headers: authHeader() });
    }
}

export default new UserService();

auth.service.js :

import axios from 'axios';

const API_URL = 'http://localhost:8088/' +
    'testproject/api';

class AuthService {
    login(user) {
        return axios({
            method: 'post',
            url: API_URL + '/login',
            headers: {"Content-Type": "application/json"},
            data: {
                username: this.username,
                password: this.password
            }
        })
            .then((response) => {
                this.loginResponse = response;
                console.log("login response: " +
                    JSON.stringify(this.loginResponse));
                localStorage.setItem('user', JSON.stringify(response.data));

                if (response.data.accessToken) {
                    localStorage.setItem('user', JSON.stringify(response.data));
                }

                return response.data;
            })
            .catch(function (err) {
                /* ... */
                console.log("there was an error in request");
                console.log(err);

                return err;
            });
    }

    logout() {
        localStorage.removeItem('user');
    }

    register(user) {
        return axios.post(API_URL + '/signup', {
            username: user.username,
            email: user.email,
            password: user.password
        });
    }
}

export default new AuthService();

Login.vue :

<template>
    <form v-on:submit.prevent="sendLogin()"
          id = "login-form" class="hover:shadow-2xl
                cursor-pointer
                 transform
                duration-300
                hover:-translate-y-1
                rounded-lg shadow-lg
                w-4/5 lg:w-2/3 bg-white rounded shadow">

        <div class="pt-8 py-4 px-8 flex flex-col
                            content-center justify-center">
            <div class = "mb-4">Login</div>

            <div class="mb-6 ">
                <input v-model = "user.username" class="border
                        rounded w-3/4 py-2 px-3"
                       id="username"
                       type="username" placeholder="Your username">
            </div>
            <div class="mb-6 ">
                <input v-model = "user.password" class="border
                        rounded w-3/4 py-2 px-3"
                       id="password"
                       type="password" placeholder="Your password">
            </div>

            <div class="flex items-center justify-between mt-8">
                <button class="header bg-blue-700
                         hover:bg-blue-dark
                          font-bold py-2 px-4
                          rounded-full" type="submit">
                    Login
                </button>
            </div>
        </div>
    </form>
</template>


<style lang="scss" scoped>...</style>

<script>
    import axios from 'axios';
    import Profile from '../user/Profile.vue'
    import User from '../../models/user.js';

    export default {
        name: 'App',
        components: {
            Profile, User
        },
        data() {
            return {
                user: new User('', '')
            }
        },
        computed: {
            loggedIn() {
                return this.$store.state.auth.status.loggedIn;
            }
        },
        created() {
            if (this.loggedIn) {
                this.$router.push('/user/' + this.user.username);
            }
        },
        methods: {
            sendLogin() {
                this.$store.dispatch("auth/login", this.user).then(
                    () => {
                        this.$router.push({
                            name: "profile",
                            props: {
                                user: this.user
                            }
                        });
                    },
                    error => {
                        console.log('big error after login');
                    }
                );

                this.$router.push({
                    name: "profile",
                    props: {
                        username: this.username
                    }
                });
            }
        }
    }
</script>

EDIT : After changing the import in main.js from import store from './store/auth.module'; to import store from './index.js'; I get this error when trying to load any page (and the page doesn't load, all I get is a white screen):

在此处输入图像描述

At a guess, I'd say the issue is here in main.js

// main.js
import store from './store/auth.module';

That appears to be importing one of your store modules which won't be a Vuex.Store instance.

In main.js , you need to import the store index.js

// main.js
import store from './index.js'

By not importing store/index.js , you're also missing the all important

Vue.use(Vuex)

Can you please check you are importing Vuex properly?

I feel the answer by phil is correct, but here is also some extra reading which might help solve the issue: cannot read property 'dispatch' of undefined in Vuex

Add this line to your main.js file:

import store from '../yourPath';

vue.$store = store

this set the store object globally. so you can access it from any component by using this

Please check whether your folder structure is like below.

store folder ->(contains) auth.module, index.js(the first code snippet you mentioned).

Now import store in to main.js like below.

import store from './store'

Now you're rest of the code should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM