首页 > 解决方案 > 当对象依赖于外部对象时,如何使对象属性具有反应性?

问题描述

tldr:

User是一个全局对象。

如果我更改show值,组件将立即更新,没关系。我想得到的是“当为User.isLoggedIn()假时,Log out元素必须隐藏。当它变为真时,元素必须显示并且Login/Signup必须隐藏。” 在我的应用程序中,这个目标将转变为另一个目标,“当我从 、 或页面重定向时loginsignup必须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();

标签: javascriptvue.jsjavascript-objectsvue-routerdynamic-arrays

解决方案


您可以在“创建”阶段替换用户的原始方法。

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();
        };
    }
};

推荐阅读