vue关于v-show的问题

代码如下:

<template>
    <div id="app" class="container">
        <nav class="navbar navbar-default">
            <ul class="nav navbar-nav">
                <li>
                    <router-link to="/home">home</router-link>
                </li>
                <li>
                    <router-link to="/message">message center</router-link>
                </li>
            </ul>
            <span class="logout" @click="logout" v-show="isLogin">log out</span>
        </nav>
        <div class="nav-content">
            <router-view></router-view>
            <div v-show="isLogin">{{isLogin}}</div>
        </div>
    </div>
</template>
<script>
    import VueRouter from 'vue-router';
    import util from './common/util';

    let router = new VueRouter();

    export default {
        data() {
            return {
                isLogin: false
            };
        },
        methods: {
            logout() {
                util.fetchData('/api/logout', 'GET', null)
                    .then(res => res.json())
                    .then(data => {
                        this.isLogin = false;
                        localStorage.isLogin = false;
                        console.log('click',this.isLogin);
                        router.push({ path: '/home' });
                    })
                    .catch(err => console.log(err));
            }
        },
        watch: {
            $route(newVal, oldVal) {
                this.isLogin = localStorage.isLogin;
                console.log('route change',this.isLogin);
            }
        },
        mounted() {
            this.isLogin = localStorage.isLogin;
            console.log('mounted', this.isLogin);
        }
    }
</script>
<style>
ul,li{list-style: none;}
nav{position: relative;}
.center{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}
.container{
    margin-top: 100px;
}

.nav-content{
    margin-top: 20px;
    border-radius: 5px;
    border: 1px solid #ddd;
    padding: 20px;
    min-height: 200px;
    position: relative;
}
.logout{
    position: absolute;
    top: 15px;
    right: 10px;
    cursor: pointer;
}
.logout:hover{
    color: #f00;
}
</style>

以下是路由代码:

import Home from '../components/Home.vue';
import Login from '../components/Login.vue';
import MessageCenter from '../components/Message-center';
import util from '../common/util';

import VueRouter from'vue-router';
const router = new VueRouter();

export default {
    routes: [
        { 
            path: '/home', 
            component: Home
        },
        {
            path: '/login',
            component: Login
        },
        { 
            path: '/message', 
            component: MessageCenter,
            beforeEnter: (to, from, next) => {
                util.fetchData('/api/checklogin', 'GET', null)
                    .then(res => res.json())
                    .then(data => {
                        if (data.isLogin == false) {
                            localStorage.isLogin = false;
                            router.push({ path: '/login' });
                        } else {
                            localStorage.isLogin = true;
                        }
                    })
                    .catch(err => console.log(err));
                next();
            }
        },
        { 
            path: '*', 
            redirect: '/home'
        }
    ]
}

clipboard.png

阅读 4.6k
1 个回答

如果我没猜错的话,应该是watchmounted里的这句

  this.isLogin = localStorage.isLogin;

造成的

localStorage里的每个值都是字符串,所以你取出来的,应该是字符串'false'。改成这样应该就好了

   this.isLogin = JSON.parse(localStorage.isLogin);

不过上面这样如果为空的话很容易报错,需要做空保护,改成下面这样应该更好一些

   this.isLogin = localStorage.isLogin == 'true';
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题