大咖直播-鸿蒙原生开发与智能提效实战!>>> 了解详情
写点什么

预填充 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:161508

评论

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

MASA MAUI Plugin (八)Android相册多选照片(Intent 方式)

MASA技术团队

.net blazor MAUI MASA Blazor

风险洞察之事件总线的探索与演进

京东科技开发者

京东云 事件总线 京东技术 数据管道 风险洞察

飞桨全量支持业内AI科学计算工具——DeepXDE!

飞桨PaddlePaddle

人工智能 深度学习 开源

AI for Science系列(三):赛桨PaddleScience底层核心框架技术创新详解

飞桨PaddlePaddle

人工智能 paddle 飞桨 框架技术

MySql基础-笔记6 -排序、分组、连接的使用、NULL值处理

MySQL 数据库

使用 NGINX 在 Kubernetes 中对 TCP 和 UDP 流量进行负载均衡

NGINX开源社区

nginx Kuber udp tpc 企业号 2 月 PK 榜

MySql基础-笔记11-临时表、复制表、元数据、序列使用

MySQL 数据库

本周 2 场直播预告!Intel 高级工程师带你探索开源机密计算社区 CCZoo | 第 65 期

OpenAnolis小助手

云计算 运维 直播 intel 龙蜥大讲堂

项目终于用上了低代码,才知道为什么真香了!

引迈信息

项目管理 低代码

软件测试/测试开发 | App测试时常用的adb命令你都掌握了哪些呢?

测试人

android 软件测试 自动化测试 测试开发 adb

MySql基础-笔记9 -ALTER命令

MySQL 数据库

AI for Science系列(一) :飞桨加速CFD(计算流体力学)原理与实践

飞桨PaddlePaddle

paddle 算法 飞桨 框架技术

案例介绍:使用A-Ops性能热点火焰图进行性能诊断

openEuler

Linux 操作系统 openEuler 性能测评 A-Ops

乌卡时代的云成本管理:从0到1了解FinOps

SEAL安全

云服务 FinOps 企业号 2 月 PK 榜

推荐系统[二]:召回算法超详细讲解[召回模型演化过程、召回模型主流常见算法(DeepMF_TDM_Airbnb Embedding_Item2vec等)、召回路径简介、多路召回融合]

汀丶人工智能

自然语言处理 深度学习 推荐系统 搜索算法 召回算法

软件测试 | 霍格沃兹线下班开课啦!

测吧(北京)科技有限公司

测试

MySQL审计插件-MariaDB Audit Plugin

GreatSQL

:MySQL 数据库 maria greatsql greatsql社区

活动回顾丨研发效能度量线下沙龙圆满举办

Kyligence

数据分析 Kyligence Zen

微服务拆分治理最佳实践

京东科技开发者

数据库 微服务 京东云 京东技术 安全接口

10分钟学会使用 Loki 日志聚合系统

北京好雨科技有限公司

Kubernetes 云原生 rainbond 企业号 2 月 PK 榜

活动预告 | GAIDC 全球人工智能开发者先锋大会

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

MySql基础-笔记10-索引

MySQL 数据库

搜索EE场景排序链路升级

京东科技开发者

模型 搜索 EE 企业号 2 月 PK 榜 Explore & Exploit

直播预告 | 企业如何轻松完成数据治理?火山引擎DataLeap给你一份实战攻略!

字节跳动数据平台

数据库 大数据 数据治理 数据实践

Gluten 首次开源技术沙龙成功举办,更多新能力值得期待

Kyligence

开源技术 Gluten

AI for Science系列(二):基于AI框架的CFD工具组件!赛桨v1.0 Beta API介绍以及典型案例分享!

飞桨PaddlePaddle

深度学习 paddle API 飞桨

中科协发布2022“科创中国”开源创新榜 OceanBase开源社区入选

OceanBase 数据库

数据库 oceanbase

单元测试利器——手把手教你使用Mockito

京东科技开发者

单元测试 Mockito 京东云 安全测试 京东技术

GhatGPT在信息安全方面的应用

HummerCloud

ChatGPT

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