1

I'm trying to toggle a sign-in and sign-out button based on if a user is logged-in. I can use v-if effectively, but I have to do a page refresh to see the toggle occur. Ie when you sign-out you have to reload the page to change the 'logout' button into a 'login' one.

Template:

      <div v-if="signedIn">
        <v-btn  class="ml-4 mr-4 primary" @click="logout">
          <span>Sign Out</span>
          <v-icon>mdi-logout</v-icon>
        </v-btn>
      </div>
      <div v-else>
        <v-btn class="ml-4 mr-4 primary" @click="$router.push('/login')">
          <span>Sign In</span>
          <v-icon>mdi-login</v-icon>
        </v-btn>
      </div>

JavaScript:

     data() {
       return {
         drawer: true,
         signedIn: this.$store.getters.isLoggedIn || false,
       };
     },

What would be the Vue way of handling the toggle without using a page refresh? I'm sure there's a better way, just to new at Vue and most tutorials I find don't help. Any tips, advice, or suggestions appreciated!


edit

store:

    import Vue from 'vue';
    import Vuex from 'vuex';
    import axios from 'axios';

    Vue.use(Vuex);

    export default new Vuex.Store({
      state: {
        status: '',
        token: localStorage.getItem('token') || '',
        user: {},
      },
      mutations: {
        auth_request(state) {
          state.status = 'loading';
        },
        auth_success(state, token, user) {
          state.status = 'success';
          state.token = token;
          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: 'http://localhost:5000/api/v1/login', data: user, method: 'POST' })
              .then((resp) => {
                const { token } = resp.data;
                // eslint-disable-next-line no-shadow
                const { user } = resp.data;
                localStorage.setItem('token', token);
                axios.defaults.headers.common.Authorization = token;
                commit('auth_success', token, user);
                resolve(resp);
              })
              .catch((err) => {
                console.log('err:', err.response);
                commit('auth_error');
                localStorage.removeItem('token');
                reject(err);
              });
          });
        },
        logout({ commit }) {
          return new Promise((resolve) => {
            commit('logout');
            localStorage.removeItem('token');
            delete axios.defaults.headers.common.Authorization;
            resolve();
          });
        },
      },
      getters: {
        isLoggedIn: state => !!state.token,
        authStatus: state => state.status,
      },
    });
2
  • You doing it right so there must be something else going wrong (your data is not reactive). Maybe add store setup to your question.... Commented Dec 31, 2019 at 16:35
  • @MichalLevý I added the store in Commented Dec 31, 2019 at 17:27

1 Answer 1

1

The data prop signedIn is not reactive to this.$store.getters.isLoggedIn.

Try using a computed method that returns this.$store.getters.isLoggedIn instead:

computed: {
    signedIn() {
        return this.$store.getters.isLoggedIn;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

How would that look in the template piece of the component then? Would I call the method inside the v-if? Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.