axios Vuex状态仅在页面刷新后更新

dba5bblo  于 2023-03-29  发布在  iOS
关注(0)|答案(1)|浏览(125)

所以我是Vue的新手,但在遵循本教程时遇到了一个问题:https://www.youtube.com/watch?v=uqpM7WVTKI4&t=2141s我完全复制了她的代码,但我得到了不同的行为。在用户提交登录表单后,会进行API调用,并在头部存储一个承载令牌。之后,用户会被重定向到主页,在那里他们会收到他们的名字。唯一的问题是,在用户被重定向后,hello消息不会显示,因为它认为用户没有登录。但是当手动页面刷新完成时,一切似乎都很好。
我怎样才能使用户不必手动刷新页面?
Main.js

import { createApp } from 'vue'
import App from './App.vue'
import "./assets/css/reset.css"
import "./assets/css/style.css"

// Import SweetAlert2
import VueSweetalert2 from 'vue-sweetalert2';
import 'sweetalert2/dist/sweetalert2.min.css';

import router from './router'

import './axios.js'

// import { createStore } from 'vuex'
import store from './vuex';

// const app = createApp(App)

// app.use(router)
// app.use(VueSweetalert2)
// app.use(store)
// app.mount('#app')
createApp(App)
    .use(router)
    .use(VueSweetalert2)
    .use(store)
    .mount('#app')

router.js

import { createWebHistory, createRouter } from "vue-router";
import Home from "@/components/Home.vue";
import Login from "@/components/Login.vue";
import Register from "@/components/Register.vue";

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home,
  },
  {
    path: "/login",
    name: "Login",
    component: Login,
  },
  {
    path: "/register",
    name: "Register",
    component: Register,
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

Home.vue

<template>
    <div>
        <h1 v-if="user">Hello {{ user.name }}!</h1>
        <h1 v-if="!user">You are not logged in</h1>
    </div>  
</template>

<script>
import { mapGetters } from 'vuex';

    export default{
        name: 'Home',
        computed: {
            ...mapGetters(['user'])
        },
        
        
        
    }
</script>

Nav.vue

<template>
<nav>
    <div class="header">
        <div class="logo">
            <img src="@/assets/logoipsum-250.png" alt="Logo">
        </div>

        <div class="links">
            <div class="not-logged-in" v-if="!user">
                <router-link class="button light-blue" to="/login">Login</router-link>
                <router-link class="" to="/register">Register</router-link>
            </div>
            <div class="logged-in" v-if="user">
                <a href="javascript:void(0)" @click="handleLogout" class="button light-blue">Logout</a>
            </div>

        </div>
    </div>
</nav>
</template>

<script>
import { mapGetters } from 'vuex';
    export default {
        name: 'Nav',
        
        methods: {
            handleLogout() {
                localStorage.removeItem('token');
                this.$store.dispatch('user', null);
                this.$router.push('/');
            }
        },
        computed: {
            ...mapGetters(['user'])
        }
    }
</script>

vuex.js

import { createStore } from 'vuex'

const state = {
    user: null
};

const store = createStore({
    state,
    getters: {
        user: (state) => {
            return state.user;
        }
    },
    actions: {
        user(context, user){
            context.commit('user', user);
        }
    },
    mutations:  {
        user(state, user){
            state.user = user;
        }
    }
})


export default store

Login.vue

<template>

    <div class="login-wrapper">
        <!-- .prevent is for preventing refresh on submit -->
        <form @submit.prevent="handleSubmit">
            <h1>Login</h1>

            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" name="email" id="email" v-model="email" placeholder="john@doe.com">
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" name="password" id="password" v-model="password" placeholder="*****">
            </div>
            <button type="submit" class="button light-blue">Login</button>
        </form>
    </div>
  

</template>

<script>
import axios from 'axios';

export default{
        name: 'Login',
        data() {
            return {
                email: '',
                password: '',
            }
        },
        methods: {
             async handleSubmit(){
                const response =  await axios.post('auth/login', {
                    email: this.email,
                    password: this.password

                });
                

                // Store API token
                localStorage.setItem('token', response.data.token);

                // Store user in vuex   
                this.$store.commit('user', response.data.user);
               
                this.$router.push('/');

                

                // If logged in
                // if (response.status == '200'){
                // }
            }
        }
    }
</script>

App.vue

<template>
<Nav/>
<router-view/>
</template>

<script>
import Nav from './components/Nav.vue'
import axios from 'axios';


export default {
  name: 'App',
  components: {
    Nav,
  },
  async created(){
      const response = await axios.get('user');

      this.$store.commit('user', response.data)

  }
}
</script>

<style>

</style>
zwghvu4y

zwghvu4y1#

一个解决方案是在你的州添加一个手表,就像在你的家一样。vue

watch: {
    user: {
      immediate: true,
      handler() {
        this.$forceUpdate();
      },
    },
  },

相关问题