组件未在商店更改时更新 - Vuex
Posted
技术标签:
【中文标题】组件未在商店更改时更新 - Vuex【英文标题】:Component not updating on store change - Vuex 【发布时间】:2018-08-19 19:49:24 【问题描述】:TLDR:
如果有帮助,我录制了一段视频来解释我的问题。 https://youtu.be/Qf9Q4zIaox8
导航栏组件不会在商店更改时更新。
我使用 v-if 和 v-else 将组件分为两个部分。当用户登录时显示 v-if,当用户未登录时显示 v-else。
当我登录时,服务器进行身份验证,客户端向存储提交一个突变并设置用户和客户端令牌。设置后,它会将状态为“userIsLoggedIn”的属性设置为 true - 此属性在导航栏组件中计算。由于未知原因,用户登录后导航栏组件不会更新(尽管 isLoggedIn 属性为 true),除非我刷新页面。
导航栏组件:
<template>
<div class="navbar">
<div class="container">
<div class="navbar-brand">
<h1 class="navbar-item">
<router-link to="/" class="has-text-black">Logo</router-link>
</h1>
</div>
<div class="navbar-menu">
<div class="navbar-end" v-if="isLoggedIn">
<div class="navbar-item">
<router-link to="/play" class="has-text-black">Play</router-link>
</div>
<div class="navbar-item">
user.balance.toFixed(2)
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link">
user.username
</a>
<div class="navbar-dropdown">
<div class="navbar-item">Profile</div>
<div class="navbar-item">Deposit</div>
<div class="navbar-item" @click="logout">Logout</div>
</div>
</div>
<div class="navbar-item">
FAQ
</div>
</div>
<div class="navbar-end" v-else>
<div class="navbar-item">
<router-link to="/login" class="has-text-black">Login</router-link>
</div>
<div class="navbar-item">
<router-link to="/register" class="has-text-black">Register</router-link>
</div>
<div class="navbar-item">FAQ</div>
</div>
</div>
</div> <!-- container -->
</div> <!-- navbar -->
</template>
<script>
import mapGetters from "vuex";
export default
name: "Navbar",
data()
return
user: this.$store.state.user,
,
computed:
...mapGetters([
"isLoggedIn",
])
,
methods:
logout()
this.$store.dispatch("setToken", null);
this.$store.dispatch("setUser", null);
this.$router.push(
path: "/"
)
</script>
Vuex 商店:
import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate"
Vue.use(Vuex);
export default new Vuex.Store(
strict: true,
plugins: [
createPersistedState()
],
state:
token: null,
user: null,
isUserLoggedIn: false,
,
getters:
isLoggedIn(state)
return state.isUserLoggedIn;
,
mutations:
setToken(state, token)
state.token = token;
if (token)
state.isUserLoggedIn = true;
else
state.isUserLoggedIn = false;
,
setUser(state, user)
state.user = user;
,
actions:
setToken (commit, token)
commit("setToken", token);
,
setUser (commit, user)
commit("setUser", user);
)
登录组件:
<template>
<div class="hero is-large">
<div class="container">
<div class="hero-body">
<div class="field">
<div class="notification is-warning" v-show="error">error</div>
</div>
<h1 class="title">Login</h1>
<div class="field">
<label for="username" class="name">Username</label>
<input type="text" class="input" name="username" v-model="username">
</div>
<div class="field">
<label for="username" class="name">Password</label>
<input type="password" class="input" name="password" v-model="password">
</div>
<div class="field">
<button class="button is-link"
@click="login"
v-bind:class="'is-loading': pending">Login</button>
</div>
</div>
</div>
</div>
</template>
<script>
import AuthenticationService from "../Services/AuthenticationService";
export default
name: "Login",
data ()
return
username: "",
password: "",
error: null,
pending: false,
,
methods:
async login ()
try
// SET LOADING SPINNER
this.pending = true;
// API REQUEST
const response = await AuthenticationService.login(
username: this.username,
password: this.password,
);
console.log(response);
// CLEAR FORM
this.pending = false;
this.username = "";
this.password = "";
this.$store.dispatch("setToken", response.data.token);
this.$store.dispatch("setUser", response.data.user);
this.$router.push(
name: "Landing"
)
catch (error)
console.log(error);
</script>
【问题讨论】:
显示你做的部分this.$store.dispatch("setToken", <SOMETHING not null>);
好的 - 我已将代码附加到帖子“登录组件”
变异可能有问题吗?您可以使用 VueDevtools 之类的插件在浏览器中检查商店的状态。
我下载了 chrome 工具,按照建议做了。突变工作正常,状态正在正确更新。由于某种原因,一旦状态改变,v-if 和 v-else 块就不会改变。
【参考方案1】:
我想我发现了问题所在。当用户登录时,您没有将 isUserLoggedIn 设置为 true。因此,当用户成功登录时,执行一个操作,然后将 isUserLoggedIn 更改为 true。
动作
setUserLogged (commit)
commit("setUserLogged", true);
变异
setUserLogged(state, payload)
state.isUserLoggedIn = true
然后在登录组件中的这些行中更改:
this.$store.dispatch("setToken", response.data.token);
this.$store.dispatch("setUser", response.data.user);
到这里:
this.$store.dispatch("setToken", response.data.token);
this.$store.dispatch("setUser", response.data.user);
this.$store.dispatch("setUserLogged");
【讨论】:
如果我错了,请原谅我,但你确定吗?我在 setToken Mutation 突变中将 isUserLoggedIn 状态设置为 true: setToken(state, token) state.token = token; if (token) state.isUserLoggedIn = true; 其他 state.isUserLoggedIn = false; ,
更新-无论如何我都尝试了你的建议。我没有工作:(
我在我的项目和作品中做了同样的事情。问题将出在登录组件中。尝试删除异步和所有其他东西,只向服务器发出登录请求。在调用栏中“然后”放你派遣
实际上在更改登录方法之前...在导航栏组件中尝试将“用户”属性设置为空字符串('')并在计算方法中从 vuex 存储中获取用户。为此还需要创建另一个返回用户的吸气剂
嘿,我做到了,它奏效了。我需要设置一个计算方法来从商店获取用户,并且效果很好。太感谢了。一整天都在烦我。以上是关于组件未在商店更改时更新 - Vuex的主要内容,如果未能解决你的问题,请参考以下文章