vue.js - 为什么我的 Vue/Vuex 订阅者没有被触发?

标签 vue.js vuex vue-router subscribe buefy

我已经设置了我的 Vuex 订阅功能来将用户身份验证存储在 localStorage 中,但我一生都无法弄清楚为什么订阅者根本不触发。我什至无法从中获取 console.log() 。这是我的项目的相关内容。

ma​​in.js

import Vue from 'vue';
import Buefy from 'buefy';
import axios from 'axios';
import router from '@/router';
import store from '@/store';
import App from './App.vue';
import 'buefy/dist/buefy.css';
import '@/store/subscriber';

Vue.config.productionTip = false;

Vue.use(Buefy);

Vue.prototype.$http = axios;
const token = localStorage.getItem('x-auth-token');
if (token) Vue.prototype.$http.defaults.headers.common['x-auth-token'] = token;
Vue.prototype.$http.defaults.baseURL = 'http://localhost:5000/v1/';

new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');

store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import auth from './auth';
import transactions from './transactions';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    auth,
    transactions,
  },
});

store/subscriber.js

import Vue from 'vue';
import store from '@/store';

store.subscribe = (mutation) => {
  console.log(mutation);
  console.log("WHY AREN'T YOU WORKING!!!???");

  switch (mutation.type) {
    case 'auth/SET_TOKEN':
      if (mutation.payload) {
        Vue.prototype.$http.defaults.headers.common['x-auth-token'] = mutation.payload;
        localStorage.setItem('x-auth-token', mutation.payload);
      } else {
        Vue.prototype.$http.defaults.headers.common['x-auth-token'] = '';
        localStorage.removeItem('x-auth-token');
      }
      break;
    case 'auth/SET_USER':
      if (mutation.payload) {
        Vue.prototype.$http.defaults.headers.common.user = JSON.stringify(mutation.payload);
        localStorage.setItem('user', JSON.stringify(mutation.payload));
      } else {
        Vue.prototype.$http.defaults.headers.common.user = '';
        localStorage.removeItem('user');
      }
      break;
    default:
      Vue.prototype.$http.defaults.headers.common['x-auth-token'] = '';
      Vue.prototype.$http.defaults.headers.common.user = '';
  }
};

store/auth.js

import axios from 'axios';

export default {
  namespaced: true,
  state: {
    token: localStorage.getItem('x-auth-token') || '',
    user: {},
  },
  getters: {
    authenticated(state) {
      return state.token && state.user;
    },
    user(state) {
      return state.user;
    },
  },
  mutations: {
    SET_TOKEN(state, token) {
      state.token = token;
    },
    SET_USER(state, data) {
      state.user = data;
    },
  },
  actions: {
    async signIn({ commit, dispatch }, credentials) {
      try {
        const { data } = await axios.post('users/login', credentials);
        const { token, user } = data;
        if (token) {
          commit('SET_TOKEN', token);
        }
        commit('SET_USER', user);
        return data;
      } catch (err) {
        dispatch('signOut');
        return err.response;
      }
    },
    async registerUser({ commit, dispatch }, credentials) {
      try {
        const { data } = await axios.post('users/register', credentials);
        const { token, user } = data;
        if (token) {
          commit('SET_TOKEN', token);
        }
        commit('SET_USER', user);

        return data;
      } catch (err) {
        dispatch('signOut');
        return err.response;
      }
    },
    signOut({ commit }) {
      commit('SET_TOKEN', '');
      commit('SET_USER', {});
    },
  },
};

views/LogIn.vue

<template>
  <div>
    <h1 class="title has-text-centered is-size-1 mt-6">Log In</h1>
    <div class="box column is-half is-offset-one-quarter mt-6 px-6">
      <form @submit.prevent="handleSubmit" action="GET" class="my-5">
        <b-field label="Username" for="username" :type="usernameValidation">
          <b-input v-model="user.username" id="username" name="username" placeholder="Username"></b-input>
        </b-field>
        <b-field
          label="Password"
          for="password"
          :type="passwordValidation"
          :message="passwordMessage"
        >
          <b-input
            v-model="user.password"
            type="password"
            id="password"
            name="password"
            placeholder="Password"
            password-reveal
          ></b-input>
        </b-field>
        <div class="buttons is-centered">
          <b-button native-type="submit" class="is-success mt-5 mb-4 has-text-weight-bold">Log In</b-button>
        </div>
        <div class="level">
          <div class="level-left">
            <router-link class="level-item" to="/signup">Sign Up</router-link>
          </div>
          <div class="level-right">
            <router-link class="level-item" to="/forgotpassword">Forgot Password</router-link>
          </div>
        </div>
      </form>
    </div>
  </div>
</template>
<script>
import { mapActions } from 'vuex';

export default {
  name: 'LogIn',
  data: () => ({
    user: {
      username: '',
      password: '',
    },
    usernameValidation: '',
    passwordValidation: '',
    passwordMessage: '',
  }),
  methods: {
    ...mapActions({
      signIn: 'auth/signIn',
    }),
    async handleSubmit() {
      const { data } = await this.signIn(this.user);
      if (data) {
        this.usernameValidation = 'is-danger';
        this.passwordValidation = 'is-danger';
        this.passwordMessage = data.message;
      } else {
        this.$router.push('/');
      }
    },
  },
};
</script>

最佳答案

你绝对会踢自己的。

两个问题

  1. 您没有包含 subscribe.js 文件,因此您的订阅者从未被订阅。您已将其导入 main.js 中,从而解决了该问题。
  2. store.subscribe()是一个您要调用的函数,提供订阅者函数,但您正在为其分配一个新函数。试试这个吧
store.subscribe((mutation) => {
  console.log(mutation);
  console.log("OMG YOU'RE WORKING!!!");

  // etc
})

Edit goofy-architecture-pknzm

关于vue.js - 为什么我的 Vue/Vuex 订阅者没有被触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63696555/

相关文章:

typescript - 如何在 vuex-module-decorators 中使用 MutationAction?

redirect - 我如何重定向到第一个子组件 vue 路由器

vue.js - Nuxt.js:从 vuex 开始加载指示器

javascript - Axios请求内部调用函数(then)[Vuejs]

jquery - 在 vuejs 中使用列表框的数据绑定(bind)问题

javascript - 使用 Axios 取消之前的 API 请求

javascript - Vue 将电影添加到收藏夹

javascript - Vue.js 中的条件路由

vue.js - Vue js - 从对话框获取答案以确认导航 w/Vue Router + Vuetify

javascript - 添加图层时 Mapbox 样式在缩放时更改/中断