1、什么是Token
Token是用户登录成功之后服务端返回的一个身份令牌,在项目中经常要使用。
例如:访问需要授权的API接口、校验页面的访问权限等。
同时,这里我们还需要将token数据进行存储,这样在访问其它的页面组件的时候,就可以获取token数据来进行校验。
2、token数据存储在哪里呢?
第一种情况存储在本地:
存储到本地的问题是,数据不是响应式的。
第二种情况存储到vuex中:
存储到vuex中获取方便,并且是响应式的。但是存储到vuex中也会有问题,就是当我们刷新浏览器的时候,数据就会丢失,所以还是需要把token数据存放到本地,存储到本地的目的就是为了进行持久化。
所以这里我们需要在登录成功以后,把token数据存储到vuex中,这样可以实现响应式,在本地存储就是为了解决持久化的问题。
3.配置vuex
第一步安装最新版本的Vuex:
npm install vuex@next --save
第二步在src目录下面创建store目录,在store目录中index.js文件,该文件中的代码如下所示:
import { createStore } from "vuex";const store = createStore({ state: { //存储当前登录用户信息,包含token等数据 user: null, }, mutations: { setUser(state, data) { state.user = data; }, },});export default store;
在上面的代码中,创建了store容器,同时指定了state对象,在该对象中定义user属性存储登录用户信息。
在mutations中定义setUser方法,完成用户信息的更新。
下面,要实现的就是,当登录成功以后,更新user这个状态属性。
第三步把store注入到Vue的实例中:
import { createApp } from "vue";import App from "./App.vue";import Vant from "vant";import "vant/lib/index.css";import "amfe-flexible";import "./styles/index.css";import router from "./router";import store from "./store"; //导入storecreateApp(App).use(Vant).use(router).use(store).mount("#app"); //完成store的注册操作
在main.js文件中,我们导入了store,并且注册到了Vue实例中。
第四步在登陆页面中,把登录信息存储到store容器中:
import { reactive, toRefs, ref } from "vue";import { login, sendSms } from "../../api/user";import { Toast } from "vant";import { useStore } from "vuex"; //导入useStore
在代码中导入useStore。
export default { setup() { const loginForm = ref(); //获取store const store = useStore();
在setup函数中,调用useStore方法,获取store容器。
return { ...toRefs(user), ...useSubmit(user, store),//在调用useSubmit方法的时候传递store容器 userFormRules, loginForm, };
//用户登录function useSubmit(user, store) { const onSubmit = async () => { //1、获取表单数据 //2、表单验证 //3、提交表单请求 Toast.loading({ message: "登录中...", forbidClick: true, //禁用背景点击 duration: 0, //持续时间,默认是2000毫秒,如果为0则持续展示 }); const res = await login(user); if (res.data.code === 0) { store.commit("setUser", res.data); Toast.success("用户登录成功"); } else { Toast.fail("用户名或密码错误"); } //4、根据请求响应结果处理后续操作。 }; return { onSubmit, };}
登录成功以后,获取到返回的数据,同时调用store中的commit方法完成数据的保存
我们虽然把登录成功的数据,存储到Vuex中,但是当我们刷新浏览器的时候,Vuex中的数据还是会丢失的。所以这里,我们还需要将其存储到本地中。
第五步将Token其存储到本地中:
下面修改一下store/index.js文件中的代码:
import { createStore } from "vuex";const TOKEN_KEY = "TOUTIAO_USER";const store = createStore({ state: { //存储当前登录用户信息,包含token等数据 // user: null, user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)), }, mutations: { setUser(state, data) { state.user = data; window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user)); }, },});export default store;
在mutations中的setUser方法中,将登录成功的用户数据存储到了localStorage中,在存储的时候,将数据转成了字符串。
同时在state中获取数据的时候,就从localStorage中获取,当然获取的时候,再将其转换成对象的形式。
4.封装本地存储操作
在我们的项目中,有很多的地方都需要获取本地存储的数据,如果每次都写:
JSON.parse(window.localStorage.getItem(TOKEN_KEY)),window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user));
就比较麻烦了。所以这里我们建议把操作本地数据单独的封装到一个模块中。
在utils目录下面创建storage.js文件,该文件中的代码如下所示:
// 存储数据export const setItem = (key, value) => { //将数组,对象类型的数据转换为JSON格式的字符串进行存储 if (typeof value === "object") { value = JSON.stringify(value); } window.localStorage.setItem(key, value);};//获取数据export const getItem = (key) => { const data = window.localStorage.getItem(key); //这里使用try..catch的,而不是通过if判断一下是否为json格式的字符串,然后在通过parse进行转换呢,目的就是是为了方便处理,因为对字符串进行判断看一下是否为json格式的字符串,比较麻烦一些。还需要通过正则表达式来完成。而通过try..catch比较方便 // 如果data不是一个有效的json格式字符串,JSON.parse就会出错。 try { return JSON.parse(data); } catch (e) { return data; }};//删除数据export const removeItem = (key) => { window.localStorage.removeItem(key);
下面返回到store/index.js文件中,修改对应的代码,这里使用我们上面封装好的代码。
import { createStore } from "vuex";import { getItem, setItem } from "../utils/storage";const TOKEN_KEY = "TOUTIAO_USER";const store = createStore({ state: { //存储当前登录用户信息,包含token等数据 // user: null, // user: JSON.parse(window.localStorage.getItem(TOKEN_KEY)), user: getItem(TOKEN_KEY), }, mutations: { setUser(state, data) { state.user = data; setItem(TOKEN_KEY, state.user); // window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user)); }, },});export default store;
在上面的代码中,我们导入getItem和setItem两个方法,然后在存储登录用户信息,和获取登录用户信息的时候,直接使用这两个方法,这样就非常简单了。
下面返回浏览器进行测试。
把以前localStorage中存储的内容删除掉。
然后重新输入用户名和密码,发现对应的localStorage中存储了对应的数据。