Дочерние компоненты Vuex не могут получить к нему доступ. $ Store (undefined) - PullRequest
0 голосов
/ 01 ноября 2018

Я следовал этим инструкциям в документации Vuex для доступа к состоянию Vuex из моих компонентов Vue ... но всякий раз, когда я использую this.$store.something в своих компонентах, я получаю TypeError: Cannot read property 'something' of undefined (см. Скриншот на нижняя часть этого поста).

В документации написано,

Предоставив параметр хранилища корневому экземпляру, хранилище будет вводится во все дочерние компоненты корня и будет доступен на них как на этом. $ 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 голосов
/ 26 июня 2019

Используйте Destructuring при импорте 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/>'
})

К

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/>'
})

Это сработало для меня .. Надеюсь, это сработает и для вас!

0 голосов
/ 01 ноября 2018

Все выглядит хорошо в вашем коде. Однако в вашем файле main.js измените следующий код

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

до

new Vue({
   el: "#app",
   router,
   store,
   render: h => h(App)
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...