简体   繁体   中英

Vue TypeError: Cannot read property 'loggedIn' of undefined

Based from the error, the problem is that the getters didn't retrieve any data. I tried to change the import for store since it was setup as a default by Quasar, but it only made things worse and I tried to debug those errors for hours too. Also tried changing the default export of store and router but it's pointless since they also have built in setup from Quasar too.

Login.vue

<template>
  <div>
    <q-page>
      <h5>Login Page</h5>
      <q-input name="user" v-model="username" filled label="Username" />
      <q-input name="pass" v-model="password" filled label="Password" />
      <q-btn @click="login" label="Login" />
      <li v-if="!loggedIn">
        <router-link to="/register">Register</router-link>
      </li>
    </q-page>
  </div>
</template>

<script>
import { mapMutations } from "vuex";

export default {
  name: "login",
  data() {
    return {
      username: "",
      password: ""
    };
  },
  computed: {
    loggedIn() {
      return this.$store.getters.loggedIn;
    }
  },
  methods: {
    login() {
      this.$store
        .dispatch("LOGIN", {
          username: this.username,
          password: this.password
        })
        .then(response => {
          this.$router.push("/addsub");
        })
        .catch(error => {
          console.log(error);
        });
    }
  }
};
</script>

<style>
</style>

store.js

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

import { getField, updateField } from 'vuex-map-fields'
import axios from 'axios'

// import example from './module-example'

Vue.use(Vuex)

/*
 * If not building with SSR mode, you can
 * directly export the Store instantiation;
 *
 * The function below can be async too; either use
 * async/await or return a Promise which resolves
 * with the Store instance.
 */

export default function (/* { ssrContext } */) {
  const Store = new Vuex.Store({
    modules: {
      // example
    },
    state: {
      token: localStorage.getItem('access_token') || null,
      subData: {
        subjectName: ''
      },
      testItems: {
        testId: '',
        subjectName: '',
        existingTest: '',
        question: '',
        answer: '',
        studentAnswer: ''
      }
    },
    mutations: {
      sendData: state => {
        const config = {
          headers: { 'Content-Type': 'application/json' }
        }
        axios
          .post(
            'http://localhost/MyComposer/?submitId=0',
            {
              subjectName: state.subData.subjectName
            },
            config
          )
          .then(res => {
            console.log(res)
            alert(res.data)
          })
          .catch(error => {
            console.log(error.response)
          })
      },
      //FOR TEACHER
      submitTestData: state => {
        const config = {
          headers: { 'Content-Type': 'application/json' }
        }
        axios
          .post(
            'http://localhost/MyComposer/?submitId=1',
            {
              subjectName: state.testItems.subjectName,
              question: state.testItems.question,
              answer: state.testItems.answer
            },
            config
          )
          .then(res => {
            console.log(res)
            alert(res.data)
          })
          .catch(error => {
            console.log(error.response)
          })
      },
      //FOR STUDENT
      submitData: state => {
        const config = {
          headers: { 'Content-Type': 'application/json' }
        }
        axios
          .post(
            'http://localhost/MyComposer/?submitId=2',
            {
              existingTest: state.testItems.existingTest,
              studentAnswer: state.testItems.studentAnswer
            },
            config
          )
          .then(res => {
            console.log(res)
            alert(res.data)
          })
          .catch(error => {
            console.log(error.response)
          })
      },
      updateField,
      logMeIn (state, token) {
        state.token = token
      },
      destroyToken (state) {
        state.token = null
      }
    },
    getters: {
      getField,
      loggedIn (state) {
        return state.token != null
      }
    },
    actions: {
      LOGIN (context, payload) {
        return new Promise((resolve, reject) => {
          axios
            .post('http://localhost/MyComposer/?submitId=3', payload)
            .then(response => {
              console.log(payload.username)
              console.log(payload.password)
              console.log(response.data)
              console.log(response.data.username)
              console.log(response.data.password)
              for (var i = 0; i < response.data.length; i++) {
                if (
                  response.data[i].Username === payload.username &&
                  response.data[i].Password === payload.password
                ) {
                  alert('Logged In Successfully!')
                  console.log(payload)
                  console.log(response.data)
                  resolve(response)

                  const token = response.data[i].UserId
                  console.log(token)
                  localStorage.setItem('access_token', token)
                  context.commit('logMeIn', token)
                }
              }
            })
            .catch(error => {
              reject('Incorrect Username or password. Please try again!')
              console.log(error)
            })
        })
      },
      destroyToken (context) {
        axios.defaults.headers.common['Authorization'] =
          'Bearer ' + context.state.token
        if (context.getters.loggedIn) {
          return new Promise((resolve, reject) => {
            axios
              .post('http://localhost/MyComposer/')
              .then(response => {
                for (var i = 0; i < response.data.length; i++) {
                  if (
                    response.data[i].Username === payload.username &&
                    response.data[i].Password === payload.password
                  ) {
                    alert('Logged In Successfully!')
                    console.log(payload)
                    console.log(response.data)
                    resolve(response)

                    console.log(token)
                    localStorage.removeItem('access_token')
                    context.commit('destroyToken')
                  }
                }
              })
              .catch(error => {
                localStorage.removeItem('data')
                context.commit('destroyToken')
                console.log(error)
              })
          })
        }
      }
    },
    // enable strict mode (adds overhead!)
    // for dev mode only
    strict: process.env.DEV
  })

  return Store
}

Router.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
// import { store } from '../store/index'
import { store } from 'quasar/wrappers'

Vue.use(VueRouter)

/*
 * If not building with SSR mode, you can
 * directly export the Router instantiation;
 *
 * The function below can be async too; either use
 * async/await or return a Promise which resolves
 * with the Router instance.
 */

export default function (/* { store, ssrContext } */) {
  const router = new VueRouter({
    scrollBehavior: () => ({ x: 0, y: 0 }),
    routes,
    store,
    // Leave these as they are and change in quasar.conf.js instead!
    // quasar.conf.js -> build -> vueRouterMode
    // quasar.conf.js -> build -> publicPath
    mode: process.env.VUE_ROUTER_MODE,
    base: process.env.VUE_ROUTER_BASE
  })

  router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
      if (store.getters.loggedIn) {
        next({
          path: '/'
          // query: { redirect: to.fullPath }
        })
      } else {
        next()
      }
    } else if (to.matched.some(record => record.meta.requiresVisitor)) {
      if (store.getters.loggedIn) {
        next({
          path: '/addsub'
          // query: { redirect: to.fullPath }
        })
      } else {
        next()
      }
    } else {
      next() // make sure to always call next()!
    }
  })

  return router
}

routes.js

// import VueRouter from 'vue-router'

// const router = new VueRouter({
const routes = [
  {
    path: '/',
    component: () => import('layouts/MyLayout.vue'),
    children: [
      {
        path: '',
        component: () => import('pages/Index.vue')
      },
      {
        path: '/subjectntestlist',
        component: () => import('pages/SubTestList.vue'),
        meta: {
          requiresAuth: true
        }
      },
      {
        path: '/addsub',
        component: () => import('pages/FormData.vue'),
        meta: {
          requiresAuth: true
        }
      },
      {
        path: '/logout',
        component: () => import('pages/Logout.vue'),
        meta: {
          requiresAuth: true
        }
      },
      {
        path: '/register',
        component: () => import('pages/Register.vue'),
        meta: {
          requiresVisitor: true
        }
      },
      {
        path: '/newtest',
        component: () => import('pages/AddTest.vue'),
        meta: {
          requiresAuth: true
        }
      },
      {
        path: '/testlist',
        component: () => import('pages/TestList.vue'),
        meta: {
          requiresAuth: true
        }
      }
    ]
  }
]
// })

// Always leave this as last one
if (process.env.MODE !== 'ssr') {
  routes.push({
    path: '*',
    component: () => import('pages/Error404.vue')
  })
}

export default routes

I finally got it working. If you're going to work in Quasar, just un-comment out something they made for you, aka reserved words. I solved my problem by doing so instead of creating a new Vue component just to call out the store. Also, you don't have to remove the export defaults at all because they are actually very helpful with easier connections with other components.

export default function ({ store, ssrContext } /* { store, ssrContext } */) { <-- This was commented out before
  const router = new VueRouter({
    scrollBehavior: () => ({ x: 0, y: 0 }),
    routes,
    // Leave these as they are and change in quasar.conf.js instead!
    // quasar.conf.js -> build -> vueRouterMode
    // quasar.conf.js -> build -> publicPath
    mode: process.env.VUE_ROUTER_MODE,
    base: process.env.VUE_ROUTER_BASE
  })

  router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
      if (!store.getters.loggedIn) {
        next({
          path: '/'
          // query: { redirect: to.fullPath }
        })
      } else {
        next()
      }
    } else if (to.matched.some(record => record.meta.requiresVisitor)) {
      if (store.getters.loggedIn) {
        next({
          path: '/addsub'
          // query: { redirect: to.fullPath }
        })
      } else {
        next()
      }
    } else {
      next() // make sure to always call next()!
    }
  })

  return router
}

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