vuejs能否监控localStorage的变化?

1.问题

用vue.js过程中了解到计算属性,它类似于定义了一个函数f,f的返回值依赖于某些变量a,b,c。当a,b,c中任意一个发生变化,就调用f得到新的返回值。

我现在用token做登录身份验证,使用到localStorage,在computed中编写“函数”,根据localStorage的值,在导航栏显示不同的链接:已经登录的显示“用户名”和“退出”,未登录则显示“注册”和“登录”。

我发现computed中编写的“函数”不会监控localStorage取值的变化:当我将localStorage清空后,页面并没有根据相应的条件,改变导航栏的显示。

问题:vuejs能否监控localStorage取值的变化?如果能,代码怎么写?如果不能,有哪些推荐方案?

2.代码

我的导航栏组件代码headnav.vue:

<template>
    <!-- Fixed navbar -->
    <nav class="navbar navbar-inverse navbar-fixed-top" id="navbarcolor">
      <div class="container-fluid">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a href="/" class="navbar-left"><img src="../../assets/rlogo2.png" style="height:43px;margin:auto;margin-right:20px"></a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">
          <ul class="nav navbar-nav" id="navtext">
            <li></li>
            <li>
              <ul class="dropdown-menu">
                <li><a href="#">我的网站</a></li>
              </ul>
            </li>
          </ul>
          <ul class="nav navbar-nav navbar-right" v-if="signed">            
            <li><a href="sss">{{sign_name}}</a></li> <li><a @click="logout">退出</a></li>;
          </ul>
          <ul class="nav navbar-nav navbar-right" v-else>
            <li><a v-link="{ path: 'login' }">登录</a></li> <li><a href="register.html">注册</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav>
</template>

<script>
export default {
  data () {
    return {
      sign_name: '' // 已登录时的用户名
    }
  },
  computed: {
    // 这里!判断是否已经登录
    // 但是发现不能监控localStorage的变化
    signed () {
      if (localStorage.token != null) {
        return true
      }
      return false
    }
  },
  methods: {
    logout () {
      localStorage.clear() // 清空localStorage
    }
  }
}
</script>

3.报错

也不算是大的错误,但是当点击“退出”后,页面导航栏的内容并不更新。

4.已有尝试

在组件的export default中编写了ready()方法,让页面每次加载的时候把localStorage变量存储在一个变量sign_name中,以后用这个变量sign_name来判断用户是否登录。但是这样做感觉比较麻烦的样子。

阅读 34.5k
7 个回答

所有localStorage操作都通过vuex实现

自己补充一个回答,高手请忽略,小白作为参考。

用vuex可以维护多个组件之间的共用信息,有点“全局变量”的意思。

不过我这里要在多个tab之间维护同样的登录状态,还需要配合js的事件监听函数来做。例如我把vuex脚手架搭起来,登录信息的改变相关的action和mutation都写好了,那么还需要在store.js中监听storage的变化:

// 用来维护多个标签页之间登录信息的同步
var storageHandler = function () {
  state.loginName = localStorage.name
}
window.addEventListener('storage', storageHandler, false)

参考:
Vuex: Syncing state between 2 tabs
Responding to storage changes with the StorageEvent
Event对象

Vue 仅可以对其管理的数据做响应式处理,可以理解为 data 中的数据,localStorage 并不在 Vue 的管理下,自然不会有响应特性。
要响应 localStorage 的变化,可以尝试 onStorage 事件。

新手上路,请多包涵

如果楼主不想用vuex(比如我需要修改个别小地方,没必要用庞大的vuex),建议这样操作,我也是自己想了很久,亲测可用。
在mounted中,使用监听

mounted() {
//addEventListener中this指向window,所以that指向vue实例

var that=this
window.addEventListener('storage', function(e){
//给要修改的数据加一个id,localstorage发生修改后,直接使用innerHTML方法来修改即可
  that.$refs.adminName.innerHTML=e.newValue
})

},

新手上路,请多包涵

VUEX 太敏感了, 对于SWIPER 这等消耗资源性能很强的 , 万一浏览器在处理滑动事件 时卡住了, 就会频繁无限循环的调用VUEX相关接口函数.陷入死循环 当然这种概率低 ,除非做开发经常测试才能遇到一次.

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