vue中没有更新最新的jwt令牌



我有一个问题,一旦用户登录,用户就不会用最新数据更新,我在UI中也看不到它。

User是最后一个返回的令牌对象的一部分,我可以在控制台中看到,vue加载用户的上一个状态,而不是在jwt被续订并设置为持久后使用最后一个接收到的令牌再次加载。

我想我需要在返回令牌的函数或更改的令牌属性上创建一个计算的,我不确定。。。

以下代码:

root-component.vue

<template>
<app v-bind:tokenInstance="tokenInstance" v-bind:saveUserLocales="saveUserLocales"></app>
</template>
<script>
const { getTokenInstance, getTokenInstanceFromStorage, fetchProtectedApi } = require('../auth/jwt.js');
const { onAkuoJwtChanged } = require('../jwt-akuo-token-listener.js');
const { sendToAllTabs } = require('../cross-environment-code/messaging');
const storedTokenInstance = getTokenInstanceFromStorage();
const rootComponent = {
components: {
'app': require('./app.vue')
},
data() {
return {
tokenInstance: storedTokenInstance
};
},
created() {
onAkuoJwtChanged(this.setTokenInstance);
console.log('creation of function onAkuoJwtChanged with ');
},
methods: {
setTokenInstance(jwt) {
console.log('setTokenInstance:', jwt)
this.tokenInstance = getTokenInstance(jwt);
},
// this could probably be ubstracted to a more generic `saveUser`. Maybe we will save user elsewhere too and we do not want to deal with seting token there as well
saveUserLocales(userId, locales) {
return fetchProtectedApi(`users/${userId}`, {
method: 'PUT',
body: { locales }
}).then(
({ token }) => {
this.setTokenInstance(token); // this could be removed if sending singedIn would trigger a local storage set and this in turn would trigger onAkuoJwtChanged that calls thissetTokenInstance
// here -> engine.content -> background page (where we store the token)
sendToAllTabs({
fn: 'signedIn',
message: token
}); // this is fine since both options page and background page share the same localStorage! according to this stackoverflow post: https://stackoverflow.com/a/8790423
},
(error) => {
// TODO notify user that it failed
console.error(error);
}
);
}
}
};
app.vue
<template>
<div>
<no-token v-if="displaySignIn" v-bind:tokenInstance="tokenInstance"></no-token>
<with-chosen-locales v-else v-bind:userLocales="user.locales" v-bind:saveUserLocales="saveUserLocales" v-bind:userId="userId"></with-chosen-locales>
</div>
</template>
<script>
const { getUserIntance } = require('../models/user');
module.exports = {
components: {
'no-token': require('./no-token.vue'),
'no-locales': require('./no-locales.vue'),
'with-chosen-locales': require('./with-chosen-locales.vue')
},
props: ['tokenInstance', 'saveUserLocales'],
data() {
return {};
},
computed: {
displaySignIn() {
console.log('displaySignIn: ', (!this.tokenInstance || this.tokenInstance.isExpired()));
return !this.tokenInstance || this.tokenInstance.isExpired();
},
hasNotChosenLocales() {
console.log('hasNotChosenLocales: ', (this.userInstance && !this.userInstance.hasChosenLocales()))
return this.userInstance && !this.userInstance.hasChosenLocales();
},
hasNotDetectedLocales() {
console.log('hasNotDetectedLocales: ', (this.userInstance && !this.userInstance.detectedLocales()))
return this.userInstance && !this.userInstance.detectedLocales();
},
user() {
console.log('user: ', this.tokenInstance.getUser())
return this.tokenInstance.getUser();
},
userInstance() {
console.log('userInstance: ', this.user && getUserIntance(this.user))
return this.user && getUserIntance(this.user);
},
userId() {
console.log('userId: ', (this.userInstance && this.userInstance.getJson()._id))
return this.userInstance && this.userInstance.getJson()._id;
}
}
};
</script>

带选择本地.vue

<template>
<div v-if="isEditMode === false">
<div>chosen locales</div>
<template v-for="localeObj in chosenLocales">
<div>{{localeObj.locale}}</div>
</template>
<button v-on:click="switchToEditMode">Edit</button>
</div>
<div v-else>
<div>Edit locales</div>
<template v-for="localeObj in availableLocales">
<input type="checkbox" id="localeObj.locale" v-bind:checked="localeObj.chosen" v-on:click="localeObj.chosen = !localeObj.chosen">
<label for="localeObj.locale">{{localeObj.locale}}</label>
</template>
<button v-on:click="save">Save</button>
</div>
</template>
<script>
const { fetchProtected } = require('../auth/jwt.js');
function cloneLocales(locales) {
return locales.map(x => Object.assign({}, x));
}
module.exports = {
props: ['userLocales', 'saveUserLocales', 'userId'],
data() {
return { 
componentLocales: cloneLocales(this.userLocales),
availableLocales: [],
editMode: false };
},
computed: {
chosenLocales() {
return this.componentLocales.filter(x => x.chosen);
},
isEditMode()
{
console.log('this.userLocales:', this.userLocales);
return this.editMode;
}
},
methods: {
switchToEditMode() {
return fetchProtected(`data/list.json`, {
method: 'GET'
}).then(
(v) => {
this.availableLocales = v.map(l => {
return {
locale:l,
chosen: this.chosenLocales.filter(x => x.locale === l).length > 0
};});
this.editMode = true;
},
(error) => {
// TODO notify user that it failed
console.error(error);
}
);
},
save() {
this.saveUserLocales(this.userId, this.availableLocales.filter(x => x.chosen));
this.componentLocales = this.availableLocales;
this.editMode = false;
},
}};
</script>

您的善意帮助,Assaf

您显然必须使用Vuex执行此任务。

您正在将令牌从根组件发送到子组件-是否要将此属性添加到每个需要它的组件?这就是为什么需要Vuex。它在整个应用程序中同步数据。

将所有代币接收逻辑移动到Vuex模块,如下所示:

  1. 在Vuex状态下创建令牌,并从存储中获取初始值
  2. 创建将令牌设置为存储并将令牌设置在状态中的突变
  3. 创建将调用API并将令牌传递给突变的操作
  4. 创建getter以使用Vuex中的此令牌

这里也有解释:https://scotch.io/tutorials/handling-authentication-in-vue-using-vuex

最新更新