50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

预填充 Vue.js 全局存储状态的三种方法

  • 2020-12-25
  • 本文字数:2842 字

    阅读完需:约 9 分钟

预填充Vue.js全局存储状态的三种方法

本文最初发布于 austingil.com 网站,经原作者授权由 InfoQ 中文站翻译并分享。


在构建 Vue.js 应用程序时,当这些应用程序的规模扩张到一定程度后,你就可能会遇到管理全局状态的需求了。还好,他们的核心开发团队提供了 Vuex 这个便利的工具,这是 Vue.js 应用程序状态管理库的事实标准。


要入门这个库非常简单,所以我假设你已经熟悉了 Vuex 的实现。这篇文章并不是一篇入门教程。如果你需要从头开始了解的话,那么我建议你查阅文档


Vuex 让我们可以更方便地管理全局数据存储。对于下面的示例,假设我们有一个看起来像这样的存储:


import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({  state: {    user: null  },  mutations: {    setUser (state, user) {      state.user = user    }  },})
复制代码


这个存储的初始状态有一个空的 user 对象,以及一个可以更新状态的 setUser 突变。然后,在我们的应用程序中,我们可能想要显示 user 的详细信息:


<template>  <div>    <p v-if="user">Hi {{ user.name }}, welcome back!</p>    <p v-else>You should probably log in.</p>  </div></template><script>export default {  computed {    user() {      return this.$store.state.user    }  }}</script>
复制代码


这样一来,在应用加载时,如果用户已登录,则应用会向用户显示一条欢迎消息。否则,它将告诉用户他们需要登录。我知道这是一个简单的示例,不过你可能也遇到过类似的情况。你可能也会像我一样产生这样的疑问:


如何在我的应用加载之前将数据添加到存储中?


还好,我们倒是有一些方法可选。


设置初始状态


预填充全局存储的最笨方法是在创建存储时设置初始状态:


import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({  state: {    user: { name: "Austin" }  },  mutations: {    setUser (user) {      state.user = user    }  }})
复制代码


显然,这只有在你提前知道关于用户的详细信息时才能用。可是在构建应用程序时,我们可能不知道用户会起什么名字,但是还有另一种选择。


我们可以利用 localStorage 保留用户信息的一个副本。当他们登录时,你可以在 localStorage 中设置详细信息;而当他们登出时,你可以从 localStorage 中删除详细信息。


应用加载后,你可以将用户详细信息从 localStorage 拉到初始状态里面:


import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)const store = new Vuex.Store({  state: {    user: localStorage.get('user')  },  mutations: {    setUser (user) {      state.user = user    }  }})
复制代码


如果你使用的数据不需要严格的安全限制,那么这种方法的效果会很好。我建议使用 vuex-persistedstate 库来帮助自动化这里的操作。


请记住,切勿将诸如身份验证令牌之类的非常敏感的数据存储在 localStorage 中,因为 XSS 攻击可能会将其作为目标。因此,我们的示例适合存储用户名,但不适用于身份令牌。这些敏感数据应该只存储在内存中(仍然可以选择 Vuex,只是不能持久保存)。


在应用挂载时请求数据


现在,假设出于某种原因,我们不希望将数据存储在 localStorage 中。我们的下一个选项可能是将初始状态保留为空,然后允许我们的应用程序挂载。应用挂载完毕后,我们可以向服务器发出一些 HTTP 请求以获取数据,然后更新全局状态:


<template>  <div>    <p v-if="user">Hi {{ user.name }}, welcome back!</p>    <p v-else>You should probably log in.</p>  </div></template><script>export default {  computed {    user() {      return this.$store.state.user    }  },  async mounted() {    const user = await getUser() // Assume getUser returns a user object with a name property    this.$store.commit('setUser', user)  }}</script>
复制代码


这种办法效果很好,但是现在我们有了一种奇怪的用户体验。这个应用程序将加载并发送请求,但是当用户等待请求返回时,他们会看到“你可能应该登录”的提示。当请求返回时,假设他们已登录会话,该消息将迅速更改为“Hi{{user.name}},欢迎回来!”。这种跳跃看起来会很混乱。


为了解决这个问题,我们可以在请求结束时简单地显示一个加载中的元素:


<template>  <div>    <p v-if="loading">Loading...</p>    <p v-else-if="user">Hi {{ user.name }}, welcome back!</p>    <p v-else>You should probably log in.</p>  </div></template><script>export default {  data: () => ({    loading: false  }),  computed {    user() {      return this.$store.state.user    }  },  async mounted() {    this.loading = true    const user = await fetch('/user').then(r => r.json()) // Assume getUser returns a user object with a name property    this.$store.commit('setUser', user)    this.loading = false  }}</script>
复制代码


请记住,这是一个非常简单的示例。在你自己的项目里,你可能会有用于加载动画的专用组件,并且可能有一个<router-view>组件来代替此处的用户消息。你也可以选择通过一个 Vuex 动作来发出这个 HTTP 请求。不过基本概念都是一样的。


在应用加载之前请求数据


本文的最后一个示例是发出与上一个示例中类似的 HTTP 请求,但是在应用程序加载之前,就等待请求返回并更新存储。


请记住,Vuex 存储只是具有某些属性和方法的一个对象,所以可以将它和其他任何 JavaScript 对象一样来看待。


我们可以将存储导入到 main.js 文件(或者你自己确定的应用程序入口点)中,并在挂载应用程序之前调用 HTTP 请求:


import Vue from "vue"import store from "./store"import App from "./App.vue"fetch('/user')  .then(r => r.json())  .then((user) => {    store.commit('setUser', user)    new Vue({      store,      render: (h) => h(App),    }).$mount("#app")  })  .catch((error) => {    // Don't forget to handle this  })
复制代码


这种方法的好处是,在应用程序加载之前,就会将需要从 API 获取的所有数据都预加载到全局存储中。这是避免前面提到的问题跳转或管理某些加载逻辑的便捷方法。


然而……


这里有一个警告需要注意。的确,你不必担心在 HTTP 请求挂起时应该显示什么加载提示,但与此同时,你的应用不会显示任何内容。如果你的应用程序是单页应用程序,则你的用户可能会一直盯着空白的页面,直到请求返回为止。


因此,你并没有真正解决延迟问题,只是选择了在用户等待数据时要显示哪种 UI 体验。


结束语


哪种方法更好?我没有什么确切的结论。实际上,你可以同时使用这三种方法,具体取决于你要获取的数据类型以及应用程序的需求。


我还应该提一下,我的示例是在做 fetch 请求,然后使用 Vuex 突变直接提交到存储。而你可以轻松地使用 Vuex 动作来实现 fetch。你还可以将这些原理应用于其他任何状态管理工具,例如 Vue.observable。


原文链接:


3 Ways Prepopulate Vue.js Global Stores State


2020-12-25 09:161504

评论

发布
暂无评论
发现更多内容

Paimon x StarRocks 助力喜马拉雅构建实时湖仓

StarRocks

Nginx性能优化的几个方法

江南一点雨

.NET 9 AOT的突破 - 支持老旧Win7与XP环境

沙漠尽头的狼

探索新机遇:当跨境外贸独立站挑战重重,反向海淘代购模式成为新蓝海

代码忍者

反向海淘

功能强大、简单易用的视频下载工具 4K Video Downloader for mac

Rose

Omi录屏专家 Screen Recorder by Omi Mac v1.3.9激活版

Rose

实验室辅助管理系统(源码+文档+部署+讲解)

深圳亥时科技

利用免费的Geo Location API进行实时用户分析

幂简集成

API 免费API

我的新书出版啦!和大家聊聊写书的酸甜苦辣

码哥字节

数据库 nosql 写作 redis 精讲 程序员 java

从方言对话这枚“落子”,看AI手机“棋局”的尴尬赛点

脑极体

AI

Steinberg Dorico Pro for Mac 破解补丁 及安装包

Rose

cdr 2023 mac破解版 附激活码 CorelDRAW Graphics Suite 2023中文安装包

Rose

3D摄影棚布光工具 Set A Light 3D Studio for Mac 永久版

Rose

一键制作ppt工具哪个好?5款好用的AI软件盘点!

职场工具箱

效率工具 PPT AIGC AI 人工智能 AI生成PPT

CrossOver 24 for Mac(windows 虚拟机) 附激活补丁

Rose

Acrobat Pro DC 2024,打造顶级文档处理平台

Rose

强大防护软件 Deep Freeze(冰点还原精灵),释放电脑潜能!

Rose

DataWorks:新一代 Data+AI 数据开发与数据治理平台演进

阿里云大数据AI技术

大数据 Serverless 云原生 Dataworks

基于微服务SDK框架与JavaAgent技术,低成本助力应用高效发布

华为云开发者联盟

微服务 灰度发布 java-agent Java Chassis 3

字节码文件解剖

不在线第一只蜗牛

AnyToISO Pro mac破解版:ISO镜像文件制作工具

Rose

EndNote 21 for mac 授权破解版 EndNote下载安装包

Rose

一文读懂什么是RAG,如何搭建多模态RAG降低大模型幻觉

Zilliz

Milvus LLM 大模型幻觉 多模态rag RAG搭建

预填充Vue.js全局存储状态的三种方法_语言 & 开发_Austin Gil_InfoQ精选文章