最近项目使用了Nuxt, 不过由于考虑到项目需要快速上线, 放弃了SSR, 直接采用单页面SPA模式进行开发, 也是本人第一次使用Nuxt来进行项目开发, 以下是我开发中对于鉴权这块的研究和总结, 因为官方给了一个鉴权示例是基于Server端的, 所以我就又写了一篇Client端的鉴权总结~文章分为很多篇, 会逐步完善更新, 请耐心等待...
预备知识
介绍
Nuxt.js 是一个基于 Vue.js 的通用应用框架。那么既然是基于Vue的, 它自然也就用到的Vuex, 那么会遇到一个问题, 它本是状态管理模式, 不过有时候我们会作为数据共享的一种解决方案, 但是它会在页面刷新时丢失.
因此在Vue项目开发中, 我们每次刷新获取数据可能只有两种方式:
- 每次刷新都会向服务器发送请求, 拿到数据后, 对页面重新更新视图
- 每次操作都会存在本客户端的Cookie或者Storage中
很显然一般情况下, 第一种方法会给服务器资源造成浪费, 除非需要获取的数据是频繁变化的, 那么我们一般会使用第二种. 下面就主要针对第二个方案进行总结.
需求分析
我们都知道HTTP是无状态的, 那么为了让用户每次访问页面的时候会话能够保持, 则需要用cookie或者storage来记录. 我们后台的session有效期为半小时.
在这半小时内, 用户处于登录状态, 本地也保存了有效凭证的情况下, 则该用户的有效资源请求可以被执行, 而无需服务器每次进行验证~
需求方希望本地存储的凭证会在会话关闭后清除, 因此我们首先排除localStorage
, 考虑使用Cookie
和sessionStorage
! 又因为本人比较懒, 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鉴权的过程的思考.
本人也是边在学习边实践总结, 文中如有错误还请多多指正.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。