Vuex子组件无法访问此。$ store(未定义)

时间:2018-10-31 22:04:28

标签: vue.js vuejs2 vuex

我跟随these instructions in the Vuex documentation从我的Vue组件访问Vuex状态...但是每当我在组件中使用this.$store.something时,我都会得到TypeError: Cannot read property 'something' of undefined(请参阅此底部的屏幕截图)发布)。

文档说,

  

通过向根实例提供store选项,存储将是   注入到根的所有子组件中,并且将可用   像这样。$ store

...但是该功能似乎无法在我的应用程序中正常工作。

这是我的代码:

main.js

import Vue from 'vue'
import App from './App'
import axios from 'axios'
import router from './router'
import store from './store'

Vue.config.productionTip = false
axios.defaults.baseURL = 'http://localhost:3000'

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

store.js

import Vue from 'Vue'
import Vuex from 'vuex'
import router from './router'
import axios from 'axios'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    token: null
  },
  mutations: { // setters (synchronous)
    setToken (state, userData) {
      state.token = userData.token
    },
    clearToken (state) {
      state.token = null
    }
  },
  actions: { // asynchronous tasks
    signup (authData) {
      axios.post('/user/signup', {
        email: authData.email,
        password: authData.password
      })
        .then(res => {
          if (res.status === 201) {
            // what happens if signup succeeds?
          } else {
            // what happens if signup fails?
          }
        })
        .catch(error => console.log(error))
    },
    setLogoutTimer ({commit}, expiresIn) {
      setTimeout(() => {
        commit('clearToken')
      }, expiresIn * 1000)
    },
    login ({commit, dispatch}, authData) {
      axios.post('/user/login', {
        email: authData.email,
        password: authData.password
      })
        .then(res => {
          console.log(res)

          // set token with timeout
          const now = new Date()
          const tokenExpiration = new Date(now.getTime() + res.data.expiresIn * 1000)
          localStorage.setItem('token', res.data.token)
          localStorage.setItem('tokenExpiration', tokenExpiration)
          commit('setToken', { token: res.data.token })
          dispatch('setLogoutTimer', res.data.expiresIn)

          // redirect to dashboard
          router.replace('/dashboard')
        })
        .catch(error => console.log(error))
    },
    tryAutoLogin ({commit}) {
      const token = localStorage.getItem('token')
      if (!token) {
        return
      }
      const tokenExpiration = localStorage.getItem('tokenExpiration')
      const now = new Date()
      if (now >= tokenExpiration) {
        return
      }
      commit('setToken', { token: token })
    },
    logout ({commit}) {
      commit('clearToken')
      localStorage.removeItem('token')
      localStorage.removeItem('tokenExpiration')
      router.replace('/login')
    }
  },
  getters: {
    isAuthenticated (state) {
      return state.token !== null
    }
  }
})

App.vue

<template>
  <div id="app">
    <app-header/>
    <router-view/>
  </div>
</template>

<script>
import Header from './components/Header.vue'

export default {
  name: 'App',
  components: {
    'app-header': Header
  },
  created () {
    this.$store.dispatch('tryAutoLogin')
  }
}
</script>

Header.vue

<template>
  <header id="header">
    <div class="logo">
      <router-link to="/">Home</router-link>
    </div>
    <nav>
      <ul>
        <li v-if="!auth">
          <router-link to="/signup">Sign Up</router-link>
        </li>
        <li v-if="!auth">
          <router-link to="/login">Login</router-link>
        </li>
        <li v-if="auth">
          <router-link to="/dashboard">Dashboard</router-link>
        </li>
        <li v-if="auth">
          <a @click="onLogout">Logout</a>
        </li>
      </ul>
    </nav>
  </header>
</template>

<script>
export default {
  computed: {
    auth () {
      return this.$store.state.token !== null
    }
  },
  methods: {
    onLogout () {
      this.$store.dispatch('logout')
    }
  },
  watch: {
    $route () {
      console.log('STORE: ', this.$store.state)
    }
  }
}
</script>

错误:

The errors

2 个答案:

答案 0 :(得分:0)

store导入到main.js文件中时,请使用Destructuring。

更改您的代码

import Vue from 'vue'
import App from './App'
import axios from 'axios'
import router from './router'
import store from './store'

Vue.config.productionTip = false
axios.defaults.baseURL = 'http://localhost:3000'

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

收件人

import Vue from 'vue'
import App from './App'
import axios from 'axios'
import router from './router'
import { store } from './store' //Added Destructuring

Vue.config.productionTip = false
axios.defaults.baseURL = 'http://localhost:3000'

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

它对我有用。希望它对您也有用!

答案 1 :(得分:-1)

您的代码中的所有内容看起来都很不错。但是,在您的main.js文件中,更改以下代码

new Vue({
 el: '#app',
 router,
 store,
 components: { App },
 template: '<App/>'
})

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