tldr:
User
是全局对象。
如果我更改show
的值,该组件将立即更新,没关系。
我想要获得的结果就像“ User.isLoggedIn()
变为false时,Log out
元素必须隐藏。当它变为true时,该元素必须显示并且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
。
也许我需要一些观察者,或者将User添加到我的全局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();
答案 0 :(得分:0)
基本上,您对User
对象的设计不是被动的。主动调用方法以获取当前状态更像是拉样式。
使用getter/ setter使其具有反应性或纯属性。
然后将您的User对象添加到options.data
时,vue将使其具有反应性。
因此简而言之
export default {
data(){return {User: User}}, // reactive now if methods were transormed into getters
computed: {
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: !this.User.isLoggedIn},
{title: 'Log out', to: '/logout', show: this.User.isLoggedIn},
]
}
},
}
// class AppUser as vue mixin, component, global, vuex module or wherever
export default {
// vuex
// state:
data()
{
return {
retrivals = null,
storageKey = 'appUser'
}
},
//getters :
computed:
{
// hasId(state)
hasId() {
// if id then return true
// return stete.retrivals && state.retrivals.hasOwnProperty('id') || false
return this.retrivals && this.retrivals.hasOwnProperty('id') || false
},
// hasToken(state)
hasToken()
{
// if token then return true
// return state.retrivals && state.retrivals.hasOwnProperty('jwt') || false
return this.retrivals && this.retrivals.hasOwnProperty('jwt') || false
},
// isLoggedIn(state, getters)
isLoggedIn()
{
// return getters.hasToken && getters.hasId
return this.hasToken && this.hasId
}
},
//actions:
methods: {
// retrieve({commit})
retrieve()
{
let data = {};
try {
data = JSON.parse(localStorage.getItem(this.storageKey));
} catch (e) {
console.log(e);
} finally {
}
// commit('setRetrievals', data)
this.retrivals = data
},
// clear({commit})
clear()
{
localStorage.removeItem(this.storageKey);
commit('setRetrivals', null)
this.retrivals = null
}
},
// mutations: {
// setRetrievals(state, payload){
// state.retrivals = payload
// }
}
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
window.AppUser.retrieve()
// this.$store.dispatch(`${AppUserModulePath}/retrieve`)
// this.$AppUser.retrieve()
})
export default {
computed: {
show(){return window.AppUser.isLoggedIn}
// show(){return this.$AppUser.isLoggedIn}
// show(){return this.$store.state/*.{modulename}*/.isLoggedIn}
}
}
export default {
computed: {
items(){ return [
{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: !this.$AppUser.isLoggedIn},
{title: 'Log out', to: '/logout', show: this.$AppUser.isLoggedIn},
]}
}
},
}
要深入了解vuex:
function applyMixin (Vue) { var version = Number(Vue.version.split('.')[0]); if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }); } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. var _init = Vue.prototype._init; Vue.prototype._init = function (options) { if ( options === void 0 ) options = {}; options.init = options.init ? [vuexInit].concat(options.init) : vuexInit; _init.call(this, options); }; }
所以Vue.use(vuex)
基本上是在root
上添加一个mixin,而vuexInit
则是从$store
添加了root.$options
,最后是store contains a vue instance state
的反应性成分(getters
,vuex
)
这可以应用于您的登录名/用户类。
答案 1 :(得分:0)
您可以在“创建”阶段替换用户的原始方法。
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();
};
}
};