吸气剂不更新 Vuex 中的值
getters not update value in Vuex
我不明白 getter 在 Vuex 中是如何工作的。 问题是 当注销状态中的令牌时,localStorage 变空了,但在 getter 中却没有。
在 created
中,我称之为:
created: async function () {
if (this.$store.getters.shortToken) {
this.isConfirm = true
}
console.log(
'signining', localStorage.getItem('token'), // ''
'state', this.$store.state.user.token, // ''
'getter', this.$store.getters.token // 'old-token'
)
if (this.$store.getters.token) {
await this.$router.push({ path: '/' })
}
}
和getters
有:
token: state => {
return localStorage.getItem('token') || state.user.token
}
和mutation
:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token)
Object.assign(state, payload)
}
但是,创建的控制台登录给了我空的 localStorage 令牌(这是正常的)和空的 state.token(这也是正常的)。但是,getters.token 给了我令牌(这不是正常),因为我给了 SET_TOKEN 空令牌。为什么会这样?
PS. 如果我在 getters 令牌的 return
上方添加 console.log(state.user.token, localStorage.getItem('token'))
,那么 created
钩子中的 getters.token
是空... 为什么?
还有一些在这种情况下使用代码,这是注销方法:
methods: {
async logout () {
if (await this.$store.dispatch('logOut')) {
console.log('logged out')
await this.$router.push({ path: '/signin' })
}
}
}
操作注销
async logOut (context) {
console.log('logggog')
context.commit('SET_TOKEN', {
token: ''
})
context.commit('SET_USER', {
user: null
})
return true
}
Getters 旨在根据 store state
.
计算 derived state
您遇到此问题是因为您从 Getter
中 return 计算 localStorage.getItem()
的值,这不是 store state
的值,因此它既不是 reactive
也不是 observable
.
在您的示例中,Vuex 不会在您调用 localStorage.setItem()
时重新计算 Getter 的值。
只有当 state.user.token
改变时,它才会重新计算 Getter 的值。
所以,如果你想让 Getter 正常工作,return 只是 state.user.token
的值。
您还可以在 App.vue
中添加一个 created
挂钩,它将检查 localStorage 中是否有令牌并调用 SET_TOKEN
突变,如果这是您试图通过调用完成的localStorage.getItem
在你的 Getter:
App.vue
<script>
created() {
const token = localStorage.getItem('token');
if (token != null) {
this.$store.mutations.SET_TOKEN({ token });
}
}
</script>
尽管如此,请注意 change detection caveats when using Object.assign
, because Vuex mutations follow Vue's reactivity rules。
在你的突变中你可能应该这样做:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token);
state.token = payload.token;
}
或者如果 payload
实际上是 state.user
你可以这样做:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token);
state.user = {
...payload
}
}
我不明白 getter 在 Vuex 中是如何工作的。 问题是 当注销状态中的令牌时,localStorage 变空了,但在 getter 中却没有。
在 created
中,我称之为:
created: async function () {
if (this.$store.getters.shortToken) {
this.isConfirm = true
}
console.log(
'signining', localStorage.getItem('token'), // ''
'state', this.$store.state.user.token, // ''
'getter', this.$store.getters.token // 'old-token'
)
if (this.$store.getters.token) {
await this.$router.push({ path: '/' })
}
}
和getters
有:
token: state => {
return localStorage.getItem('token') || state.user.token
}
和mutation
:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token)
Object.assign(state, payload)
}
但是,创建的控制台登录给了我空的 localStorage 令牌(这是正常的)和空的 state.token(这也是正常的)。但是,getters.token 给了我令牌(这不是正常),因为我给了 SET_TOKEN 空令牌。为什么会这样?
PS. 如果我在 getters 令牌的 return
上方添加 console.log(state.user.token, localStorage.getItem('token'))
,那么 created
钩子中的 getters.token
是空... 为什么?
还有一些在这种情况下使用代码,这是注销方法:
methods: {
async logout () {
if (await this.$store.dispatch('logOut')) {
console.log('logged out')
await this.$router.push({ path: '/signin' })
}
}
}
操作注销
async logOut (context) {
console.log('logggog')
context.commit('SET_TOKEN', {
token: ''
})
context.commit('SET_USER', {
user: null
})
return true
}
Getters 旨在根据 store state
.
derived state
您遇到此问题是因为您从 Getter
中 return 计算 localStorage.getItem()
的值,这不是 store state
的值,因此它既不是 reactive
也不是 observable
.
在您的示例中,Vuex 不会在您调用 localStorage.setItem()
时重新计算 Getter 的值。
只有当 state.user.token
改变时,它才会重新计算 Getter 的值。
所以,如果你想让 Getter 正常工作,return 只是 state.user.token
的值。
您还可以在 App.vue
中添加一个 created
挂钩,它将检查 localStorage 中是否有令牌并调用 SET_TOKEN
突变,如果这是您试图通过调用完成的localStorage.getItem
在你的 Getter:
App.vue
<script>
created() {
const token = localStorage.getItem('token');
if (token != null) {
this.$store.mutations.SET_TOKEN({ token });
}
}
</script>
尽管如此,请注意 change detection caveats when using Object.assign
, because Vuex mutations follow Vue's reactivity rules。
在你的突变中你可能应该这样做:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token);
state.token = payload.token;
}
或者如果 payload
实际上是 state.user
你可以这样做:
SET_TOKEN: (state, payload) => {
localStorage.setItem('token', payload.token);
state.user = {
...payload
}
}