1

在提交表单时,在 vuejs3/vee-validate 4 应用程序中,我尝试使用 vuex 发送请求并失败,因为我无法访问存储对象。我愿意:

<template>
  <Form @submit="onSubmit" :validation-schema="schema" class="login">
    
            <label class="col-form-label" for="email">Email:</label>
            <Field
              id="email"
              name="email"
              type="email"
              v-model="email"
              class="form-control editable_field"
              placeholder="Your email address"
              autocomplete=off
            />
            <ErrorMessage name="email" class="validation_error"/>
            ...
    
            <label class="col-form-label" for="password">Password:</label>
            <Field
              id="password"
              name="password"
              type="password"
              v-model="password"
              class="form-control editable_field"
              placeholder="Your password"
              autocomplete=off
            />
        
        <button>Submit</button>
  
  </Form>

</template>

<script>
  import appMixin from '@/appMixin'
  import app from './../../App.vue' 
  import store from '@/main' // THAT DOES NOT WORK
  import { /* ref, */ onMounted } from 'vue'
  import { Field, Form, ErrorMessage } from 'vee-validate'
  import * as Yup from 'yup'

  import mitt from 'mitt'
  const emitter = mitt()

  export default {
    name: 'loginPage',
    mixins: [appMixin],
    data: function () {
      return {
        email: 'email@site.com',
        password: '111111'
      }
    },

    components: {
      Field,
      Form,
      ErrorMessage
    },
    setup () {
      let self = this
      const schema = Yup.object().shape({
        email: Yup.string().email().required().label('Email Address'),
        password: Yup.string().min(5).required().label('Your Password')
      })

      const loginInit = async () => {
        console.log('loginInit emitter::')
        console.log(emitter)
      }

      function onSubmit (credentials) {
        alert(JSON.stringify(credentials, null, 2))
        console.log('this::')
        console.log(this) // UNDEFINED
        console.log('self::')
        console.log(self) // UNDEFINED
        console.log('app::')
        console.log(app)  // I see  in console : https://prnt.sc/vf1gx3
        console.log('store::')
        console.log(store) // UNDEFINED

        app.$store.dispatch('login', credentials)
          .then(() => this.$router.push('/'))

          //                 this.$router.push({path: '/admin/tasks'}) // DEBUGGING
          // .then(() => this.$router.push('/admin/tasks'))
          .catch(error => console.log(error))
      }

      onMounted(loginInit)

      return {
        schema,
        onSubmit
      }
    }
  }
</script>

在 src/main.js 我有:

import { createApp } from 'vue'
import { createStore } from 'vuex'
import axios from 'axios'

import App from './App.vue'
import router from './router/router.js'

import { settingCredentialsConfig } from '@/app.settings.js'

const store = createStore({
  state () {
    return {
      status: '',
      token: localStorage.getItem('token') || '',
      ...

所以在控制台我得到了错误:

Uncaught (in promise) TypeError: Cannot read property 'dispatch' of undefined

我在控制台中看到:https ://prnt.sc/vf1gx3

包.json:

{
  "dependencies": {
    "axios": "^0.20.0-0",
    "bootstrap": "^4.3.1",
    "core-js": "^3.6.5",
    "font-awesome": "^4.7.0",
    "jquery": "^3.4.1",
    "mitt": "^2.1.0",
    "moment-timezone": "^0.5.31",
    "node-sass": "^4.12.0",
    "popper.js": "^1.16.0",
    "sass-loader": "^10.0.4",
    "vee-validate": "^4.0.0-beta.18",
    "vue": "^3.0.0",
    "vue-router": "^4.0.0-rc.1",
    "vuex": "^4.0.0-rc.1",
    "yup": "^0.29.3"
  },
}

src/main.js :

import { createApp } from 'vue'
import { createStore } from 'vuex'
import axios from 'axios'

import App from './App.vue'
import router from './router/router.js'

import 'bootstrap'
import 'font-awesome/css/font-awesome.css'

import { settingCredentialsConfig } from '@/app.settings.js'

const store = createStore({
  state () {
    return {
      status: '',
      token: localStorage.getItem('token') || '',
      user: null,
    }
  },
  mutations: {
    auth_request (state) {
      state.status = 'loading'
    },

    auth_success (state, data) {
      state.status = 'success'
      state.token = data.token
      localStorage.setItem('token', data.token)

      state.user = data.user
      localStorage.setItem('user', JSON.stringify(data.user))
    },

    auth_error (state) {
      state.status = 'error'
    }

  },
  actions: {
    login ({ commit }, userCredentials) { // Login action
      return new Promise((resolve, reject) => {
        commit('auth_request')
        let apiUrl = process.env.VUE_APP_API_URL
        console.log('+login userCredentials::')
        console.log(userCredentials)

        console.log('+login settingCredentialsConfig::')
        console.log(settingCredentialsConfig)

        console.log('+login apiUrl::')
        console.log(apiUrl)

        // alert('apiUrl::' + apiUrl)
        axios.post(apiUrl + '/login', userCredentials, settingCredentialsConfig)
          .then((response) => {
            if (typeof response.data.access_token === 'undefined' || typeof response.data.user === 'undefined') {
              commit('auth_error') // call auth_error mutation to make changes to vuex store
              // bus.$emit('authLoggedError')
              return
            }

            const token = response.data.access_token
            const user = response.data.user
            axios.defaults.headers.common['Authorization'] = token
            commit('auth_success', {
              token: token,
              user: user
            }) // call auth_success mutation to make changes to vuex store
            // bus.$emit('authLoggedSuccess', user)
            resolve(response)
          })
          .catch((error) => {
            commit('auth_error') // call auth_error mutation to make changes to vuex store
            localStorage.removeItem('token')
            // bus.$emit('authLoggedError')
            reject(error)
          })
      })
    }, // login ({ commit }, user) { // Login action

    addUser (context, payload) {
      context.commit('addUser', payload)
    }
  },
  getters: {
    user (state) {
      return state.user
    }
  }
})

const app = createApp(App)
app.use(store)
app.use(router)

app.mount('#app')
4

1 回答 1

3

由于您使用的是组合 API,因此您应该使用useStore钩子

import {useStore} from 'vuex'

export default {
  setup(){
   
     const store=useStore();

      store.dispatch("action",payload);//instead of app.$store.dispatch("action",payload)

}
...

于 2020-11-07T09:08:05.397 回答