VueJS 更新侧边栏组件

VueJS Update Sidebar Component

我在更新组件时遇到了问题。我解释一下:

我有一个使用 VueJS 和 Vuex 的单页应用程序。我的 App.vue 是这样的:

    <template>
  <div class="wrapper">
   <Sidebar></Sidebar>
  </div>
</template>

<script>

import Sidebar from "../components/Menu/Sidebar";
export default {
  name: 'App',
  components:{Sidebar},
  props:['user'],
  updated () {
  console.log(updated)
  }
}
</script>

<style>

</style>

我的边栏组件是这样的:

  <div >
    <nav id="sidebar">
      <div id="dismiss">
        <i class="fas fa-arrow-left"></i>
      </div>
      <div class="sidebar-header">
        <h3>
          <router-link
              :to="{name:'home'}"
          >
            Gamer-Seek App
          </router-link>
        </h3>
      </div>

      <div class="components" v-if="user">
        <div class="d-flex">
          <router-link
              :to="{name: 'user_show', params:{id: user.id}}"
          >
            <img
                :src="user.image" alt="user-avatar"
                class="d-block"/>
          </router-link>
          <span class="pt-4 pl-3">Hello,<br> {{ user.username }}</span>
        </div>
      </div>
      <div v-else>
        <ul id="btn-content" class="d-flex  list-unstyled justify-content-between  components">
          <li><router-link
              :to="{name:'login'}"
          ><i class="fas fa-sign-in-alt"></i> Login
          </router-link></li>
          <li><router-link
              :to="{name:'register'}"
          ><i class="fas fa-registered"></i> Register
          </router-link></li>
        </ul>
      </div>
      <ul class="list-unstyled components">
        <li>
          <router-link
              :to="{name:'home'}"
          >
            <i class="fas fa-home"></i> Home
          </router-link>
        </li>

        <li>
          <a href="#pageSubmenu" data-toggle="collapse" aria-expanded="false" class="dropdown-toggle"><i
              class="fas fa-gamepad"></i> Games</a>
          <ul class="collapse list-unstyled" id="pageSubmenu">
            <li>
              <a href="#">Seek games</a>
            </li>
          </ul>
        </li>
        <li>
          <router-link
              :to="{name: 'about'}"
          >
            <i class="fas fa-address-card"></i> About
          </router-link>
        </li>
        <li>
          <a v-if="user" class="btn btn-danger"
             @click.prevent="logout"
          >Logout</a>
        </li>
      </ul>
    </nav>
    <div id="content">
      <menu-app></menu-app>
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
import Menu from "../Menu/Nav";

export default {
  name: 'Sidebar',
  components: {
    'menu-app': Menu
  },
  data () {
    return {
      user: ''
    }
  },
  methods: {
    logout: function () {
      this.$store.dispatch('logout')
          .then(() => {
            this.user = false;
            this.$router.push('/login')
          })
    },

  }
}
</script>

我的商店模块:

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios';
import setAuthorizationToken from "../module/axiosHeader";


Vue.use(Vuex)

export const store = new Vuex.Store({
    state: {
        status: '',
        token: localStorage.getItem('token') || '',
        user: localStorage.getItem('user') || {}
    },
    mutations: {
        auth_request(state) {
            state.status = 'loading'
        },
        auth_success(state, token) {
            state.status = 'success'
            state.token = token
        },
        auth_user(state, user){
            state.user =user
        },
        auth_error(state) {
            state.status = 'error'
        },
        logout(state) {
            state.status = ''
            state.token = ''
        },
    },
    actions: {
        login({commit}, user) {
            return new Promise((resolve, reject) => {
                commit('auth_request')
                axios({url: '/api/login_check', data: user, method: 'POST'})
                    .then(resp => {

                        const token = resp.data.token.token
                        const user = resp.data.user

                        localStorage.setItem('token', token)
                        localStorage.setItem('user', JSON.stringify(user))
                        localStorage.setItem('authenticated', 'success')

                        axios.defaults.headers.common['Authorization'] = 'Bearer ' + token

                        commit('auth_success', token)
                        commit('auth_user', user)
                        resolve(resp)
                    })
                    .catch(err => {
                        commit('auth_error')
                        localStorage.removeItem('token')
                        reject(err)
                    })
            })
        },
        register({commit}, user) {
            return new Promise((resolve, reject) => {
                commit('auth_request')
                axios({url: '/api/register', data: user, method: 'POST'})
                    .then(resp => {

                        const token = resp.data.token
                        const user = resp.data.user

                        localStorage.setItem('token', token)
                        setAuthorizationToken(token)

                        commit('auth_success', token)
                        commit('auth_user', user)
                        resolve(resp)

                    })
                    .catch(err => {
                        commit('auth_error', err)
                        localStorage.removeItem('token')
                        reject(err)
                    })
            })
        },
        logout({commit}) {
            return new Promise((resolve, reject) => {
                commit('logout')
                axios({url: '/api/logout'}).then(() => {

                        localStorage.clear();
                        setAuthorizationToken();
                        resolve()
                    }
                ).catch(error => {
                        reject(error)
                    }
                )
            })
        }

    },
    getters: {
        isLoggedIn: state => !!state.token,
        authStatus: state => state.status,
        userInfo : state => state.user
    }
})

并完成我的 Vue 实例:

import Vue from 'vue';
import router from '../routes';
import App from '../views/App';
import {store} from "../stores/authentication-store";
import Axios from "axios";
import setAuthorizationToken from "./axiosHeader";

export default class VueClass {
    static init() {

        let hours = 24; // Reset when storage is more than 24hours
        let now = new Date().getTime();
        let setupTime = localStorage.getItem('setupTime');
        if (setupTime == null) {
            localStorage.setItem('setupTime', now)
        } else {
            if (now - setupTime > hours * 60 * 60 * 1000) {
                localStorage.clear()
                localStorage.setItem('setupTime', now);
            }
        }

        router.beforeEach((to, from, next) => {
            const publicPages = ['/login', '/register'];
            const authRequired = !publicPages.includes(to.path);
            const loggedIn = localStorage.getItem('user');

            if (authRequired && !loggedIn) {
                return next('/login');
            }

            next();
        })

        Vue.prototype.$http = Axios;
        const token = localStorage.getItem('token')
        if (token) {
            setAuthorizationToken(token)
        }

        new Vue({
                el: '#app',
                store,
                router,
                template: '<App />',
                components: {App},
                data: {
                    user: ''
                },
                created: function () {
                    this.$http.interceptors.response.use(undefined, function (err) {
                        return new Promise(function (resolve, reject) {
                            if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
                                this.$store.dispatch('logout')
                            }
                            throw err;
                        });
                    });
                },
            }
        )
    }
}

我的问题是,当用户登录或注销时,如何更新我的边栏。我想在他们登录时显示他们的个人资料,否则显示 login/register。

有多种方法可以实现这一点。在这种情况下,由于边栏和用户状态是全局属性,我将使用全局事件来处理它。为此,您可以尝试 Vue 事件总线方法:

创建 event-bus.js,其中包含以下行:

import Vue from 'vue';
export const EventBus = new Vue();

app.js 中导入:

import { EventBus } from './event-bus.js';

那你就可以这样用了

发出事件(当用户登录或注销时):

EventBus.$emit('userLoggedIn', this.user);

(您也可以在商店中设置 user 而不是将其作为参数传递。)

EventBus.$emit('userLoggedOut');

您可以像这样在任何相关组件(例如您的边栏组件)中监听此事件:

导入 event-bus:

import { EventBus } from '../event-bus.js';

然后是这样的:

created() {
    EventBus.$on('userLoggedIn', () => {
        // do whatever necessary
    });

    EventBus.$on('userLoggedOut', () => {
        // do whatever necessary
    });
}