2
最近项目使用了Nuxt, 不过由于考虑到项目需要快速上线, 放弃了SSR, 直接采用单页面SPA模式进行开发, 也是本人第一次使用Nuxt来进行项目开发, 以下是我开发中对于鉴权这块的研究和总结, 因为官方给了一个鉴权示例是基于Server端的, 所以我就又写了一篇Client端的鉴权总结~

文章分为很多篇, 会逐步完善更新, 请耐心等待...

预备知识

介绍

Nuxt.js 是一个基于 Vue.js 的通用应用框架。那么既然是基于Vue的, 它自然也就用到的Vuex, 那么会遇到一个问题, 它本是状态管理模式, 不过有时候我们会作为数据共享的一种解决方案, 但是它会在页面刷新时丢失.

因此在Vue项目开发中, 我们每次刷新获取数据可能只有两种方式:

  1. 每次刷新都会向服务器发送请求, 拿到数据后, 对页面重新更新视图
  2. 每次操作都会存在本客户端的Cookie或者Storage中

很显然一般情况下, 第一种方法会给服务器资源造成浪费, 除非需要获取的数据是频繁变化的, 那么我们一般会使用第二种. 下面就主要针对第二个方案进行总结.

需求分析

我们都知道HTTP是无状态的, 那么为了让用户每次访问页面的时候会话能够保持, 则需要用cookie或者storage来记录. 我们后台的session有效期为半小时.

在这半小时内, 用户处于登录状态, 本地也保存了有效凭证的情况下, 则该用户的有效资源请求可以被执行, 而无需服务器每次进行验证~

需求方希望本地存储的凭证会在会话关闭后清除, 因此我们首先排除localStorage, 考虑使用CookiesessionStorage! 又因为本人比较懒, Cookie操作比较麻烦, 所以决定使用sessionStorage.(虽然最后还使用了插件...)

基础实例

用sessionStorage存储Vuex全局data的方式展示

创建一个Nuxt应用

我们基于Nuxt的Starter的Cli来构建一个简单的Nuxt应用, 命令如下

vue init nuxt-community/starter-template nuxt-spa-demo
cd nuxt-spa-demo
npm i

修改模式为SPA模式

修改修改nuxt.config.js, 添加mode: 'spa',, 大致如下:

module.exports = {
  mode: 'spa',
  head: {
    ...
  }
  ...
}

创建Vuex基本内容

然后store目录创建一个index.js, 代码如下

export const state = () => ({
  counter: window.sessionStorage.getItem('counter') || 0
})

export const mutations = {
  increment: state => {
    state.counter++
    window.sessionStorage.setItem('counter', state.counter)
  },
  decrement: state => {
    state.counter--
    window.sessionStorage.setItem('counter', state.counter)
  }
}

那么在Vuex的Mutatations中, 每次也会同时对sessionStorage进行操作.

另外在页面加载时, 先检查sessionStorage中是否存在counter这样一个变量, 如果没有则设置默认值0

创建一个可操作Vuex的界面

接着修改默认主页page/index.vue, 代码大致如下

<template>
  <section class="container">
    <div class="demo-wrap">
      <app-logo/>
      <h1 class="title">
        nuxt-spa-demo
      </h1>
      <h2 class="subtitle">
        Nuxt with sessionStorage or cookie
      </h2>
      <div class="content">
        <p>{{ counter }}</p>
        <p>
          <button @click="increment">+</button>
          <button @click="decrement">-</button>
        </p>
      </div>
    </div>
  </section>
</template>
<template>
  <section class="container">
    <div class="demo-wrap">
      <app-logo/>
      <h1 class="title">
        nuxt-spa-demo
      </h1>
      <h2 class="subtitle">
        Nuxt with sessionStorage or cookie
      </h2>
      <div class="content">
        <p>{{ counter }}</p>
        <p>
          <button @click="increment">+</button>
          <button @click="decrement">-</button>
        </p>
      </div>
    </div>
  </section>
</template>

<script>
import AppLogo from '~/components/AppLogo.vue'
import { mapState, mapMutations } from 'vuex'
export default {
  components: {
    AppLogo
  },
  computed: {
    ...mapState(['counter'])
  },
  methods: {
    ...mapMutations(['increment', 'decrement'])
  }
}
</script>
<style lang="scss" scoped>
...
</style>

运行应用并测试

修改基本完成后, 大致的效果可见该分支nuxt-auth-a, 然后运行应用

npm run dev

打开http://localhost:3000, 点击 +-, 数字变化后, 刷新页面, 可以观察到, 它并不会回到0, 那么一个简单的实例就完成了.

需要注意的是

  • sessionStorage的数据并不会在多个相同网站地址的窗口共享, 也就是说每次连接都是新的
  • sessionStorage存储的数据, 关闭当前标签, 重新开启, 数据会清空, 但是如果你并不是新的请求, 例如执行了__撤销上一次关闭的标签(Ctrl+Shift+T)__这样的操作, 他之前的数据依旧保留

总结

其实一个最简单的基于sessionStorage的存储数据的例子, 代码并不多, 但是一旦用于复杂的项目应用中, 也许这种处理方式并不好, 比如说需求变更带来的调整等等, 借助插件是一个不错的选择. 本次介绍的内容比较简单, 后面会逐步完善Nuxt鉴权的过程的思考.

本人也是边在学习边实践总结, 文中如有错误还请多多指正.

whidy
984 声望79 粉丝

喜欢玩游戏听歌写东西 ฅʕ•̫͡•ʔฅ