javascript - 当对象依赖于外部对象时,如何使对象属性具有反应性?
问题描述
tldr:
User
是一个全局对象。
如果我更改show
值,组件将立即更新,没关系。我想得到的是“当为User.isLoggedIn()
假时,Log out
元素必须隐藏。当它变为真时,元素必须显示并且Login/Signup
必须隐藏。” 在我的应用程序中,这个目标将转变为另一个目标,“当我从 、 或页面重定向时login
,signup
必须signout
更新这些属性(和按钮的状态)。”
Toolbar.Vue
.
脚本:
<script>
export default {
data() {
return {
items: [
{title: 'Questions', to: '/questions', show: true},
{title: 'Ask question', to: '/askQuestion', show: true},
{title: 'Categories', to: '/categories', show: true},
// only F5.
{title: 'Login/Signup', to: '/login', show: !User.isLoggedIn()},
{title: 'Log out', to: '/logout', show: User.isLoggedIn()},
]
}
},
}
一块标记:
<router-link
v-for="item in items"
:key="item.title"
:to="item.to"
v-if="item.show"
>
你知道,我正在尝试用 vue 做“注销事情”。我有那个Toolbar
组件和router-link
组件Logout
。
注意:我不User
直接在我的组件中导入类,而是在我的 app.js 中进行。像这样:
import User from './helpers/AppUser';
window.User = User;
所以,我认为每个人都有权使用User
. 此外,这个类只是一组方法。主要方法是retrieve()
。
在我Logout
的组件中有代码:
beforeMount() {
User.logout();
router.push('questions')
// window.location = '/questions'
}
所以,当我退出时,一切都很好(我正在返回问题页面),但我的Log out
按钮仍然在这里。
User.isLoggedIn()
工作正常(当我F5
的页面,一切都很好)。
我还提到如果我改变show
值,组件会立即更新,没关系。
该尝试也不起作用:
{title: 'Login/Signup', to: '/login', show: ()=> !this.isLoggedIn},
{title: 'Log out', to: '/logout', show: ()=> this.isLoggedIn},
],
}
},
computed:{
isLoggedIn: function() {
return User.isLoggedIn();
},
我的临时解决方案是使用window.location = '/questions'
而不是vue-router
. 也许我需要一些观察者,或者在我的全局 Vue 中添加用户......我不知道。
更新:用户类。
/**
* Class-helper for managing user login/signup part. Also represents the user.
*/
class AppUser {
constructor() {
this.storageKey = 'appUser';
}
/**
* retrieves user data from localStorage. if none stored, returns null
* @return {object}|{null}
*/
retrieve() {
let data = {};
try {
data = JSON.parse(localStorage.getItem(this.storageKey));
} catch (e) {
console.log(e);
} finally {
// console.log(data)
}
return data;
}
/**
* clears localStorageEntry
*/
clear() {
localStorage.removeItem(this.storageKey);
}
/**
* @return boolean
*/
hasId() {
let data = this.retrieve();
return data === null ? false : data.hasOwnProperty('id');
// if id then return true
}
/**
* @return boolean
*/
hasToken() {
let data = this.retrieve();
return data === null ? false : data.hasOwnProperty('jwt');
// if token then return true
}
isLoggedIn() {
// console.log('in user.isLoggedIn')
// try {
return this.hasToken() && this.hasId();
// }
// catch (e) {
// console.log(e);
// }
}
}
export default AppUser = new AppUser();
解决方案
您可以在“创建”阶段替换用户的原始方法。
return {
data () {
return {
items: [
{ title: 'Questions', to: '/questions', show: true },
{ title: 'Ask question', to: '/askQuestion', show: true },
{ title: 'Categories', to: '/categories', show: true },
{ title: 'Login/Signup', to: '/login', show: !User.isLoggedIn() },
{ title: 'Log out', to: '/logout', show: User.isLoggedIn() },
]
}
},
created () {
let app = this;
let items = app.items;
let loginUser = User.login.bind(User);
let logoutUser = User.logout.bind(User);
User.login = () => {
// modify the data
items[3].show = false;
items[4].show = true;
// do login
loginUser();
};
User.logout = () => {
// modify the data
items[3].show = true;
items[4].show = false;
// do logout
logoutUser();
};
}
};
推荐阅读
- python-3.x - 在基于颜色和空间节点 Networkx 聚类的图中绘制节点
- c++ - 设置 travis ci cpp 项目
- python - 满足类名时触发新的python脚本,然后在脚本完成时返回
- python - 如何将大字典序列化为磁盘文件,这样小的修改不需要完全重写,而只需要几个字节?
- asp.net-core - .NET Core - 如何从命令行或批处理调用控制器函数
- r - 如何将任何行移动到r中的最后一行数据框
- talend - 我无法在 Talend Open Studio 中检索 Clickhouse 数据库的架构。有人可以指导我吗?
- node.js - 如何找出导致我系统上“pthread_create:资源暂时不可用”的原因?
- android - 基于Firebase的React Native App中的设备-设备通信
- c# - 错误:线程试图读取或写入它没有适当访问权限的虚拟地址