【问题标题】:Vue TypeError: Cannot read property 'loggedIn' of undefinedVue TypeError:无法读取未定义的属性“loggedIn”
【发布时间】:2020-10-03 16:39:36
【问题描述】:

根据错误,问题在于 getter 没有检索到任何数据。我试图更改商店的导入,因为它是由 Quasar 设置为默认设置的,但这只会让事情变得更糟,我也尝试调试这些错误几个小时。还尝试更改存储和路由器的默认导出,但这毫无意义,因为它们也内置了来自 Quasar 的设置。

登录.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

【问题讨论】:

  • 你为什么把store放在VueRouter中?你应该把它放在new Vue({ el, router, store, render})
  • 新的 Vue 不起作用。它只是认为它与 Quasar 构建不兼容。
  • 好吧,我不知道 Quasar,但是将 store 放入 Router 对我来说看起来很奇怪。
  • 好吧,我承认把它放在那里是个错误。但是,我的导航保护代码正确吗?就像 store.getters.loggedIn 的 if else 条件一样。它不是布尔值,所以我尝试了标点符号版本。但是吸气剂没有检索任何数据。由于我可以从 Login 中看到传递的数据,因此存储已完成。
  • 终于搞定了。谢谢您的帮助。我知道把商店放在路由器里面给了我一个想法。

标签: javascript vue.js vuejs2


【解决方案1】:

我终于让它工作了。如果您要在 Quasar 工作,只需取消注释掉他们为您制作的内容,也就是保留字。我这样做解决了我的问题 而不是创建一个新的 Vue 组件来调出商店。此外,您根本不必删除导出默认值,因为它们实际上非常有助于更轻松地与其他组件连接。

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
}

【讨论】:

  • 是的,感谢您的帮助。这对我来说是一个有益的发现。
猜你喜欢
  • 2020-11-22
  • 2022-06-28
  • 2020-10-09
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 2019-08-04
  • 2020-03-28
相关资源
最近更新 更多