发布时间:2023-05-28 文章分类:WEB开发, 电脑百科 投稿人:李佳 字号: 默认 | | 超大 打印

目录

一、封装本地存储操作模块

新建文件src\utils\storage.js封装操作token的方法

二、vuex处理用户登陆后的token值

新建文件:src\store\index.js

安装导入:npm install vuex

三、封装 axios 请求模块

下载导入:npm install axios

四、在main.js文件内全局注册store、axios

五、新建api文件夹,存放接口文件

六、在组件页面内调接口拿数据

接口使用例子1

1. 登录接口的使用(同注册),在页面导入接口

2. 通过async await 来拿到用户输入的值,根据返回结果进行判断返回相应提示

接口使用例子2

1. 通过接口获取数据进行渲染,这里把需要的接口解构出来

2. data定义需要渲染的数据(可与后端字段一致)

3. 在方法里面调用接口,把拿到的数据放到一个自己定义的数组里面list

4. 通过v-for渲染获取到的数据


一、封装本地存储操作模块

新建文件src\utils\storage.js封装操作token的方法

/* 存储数据 */
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 {
    return JSON.parse(data);
  } catch (err) {
    return data;
  }
};
/* 删除数据 */
export const removeItem = (key) => {
  window.localStorage.removeItem(key);
};

二、vuex处理用户登陆后的token值

新建文件:src\store\index.js

安装导入:npm install vuex

import Vue from "vue";
import Vuex from "vuex";
// 加载storage模块:获取token,存储token
import { getItem, setItem } from "@/utils/storage";
Vue.use(Vuex);
// 用户登陆后的token值
const TOKEN_KEY = "X-Token";
export default new Vuex.Store({
  // 处理用户 Token,定义容器当中数据
  state: {
    // 用户的登录状态信息,存储当前登录用户信息(token等数据)
    // 1. user: null
    // 2. user: JSON.parse(window.localStorage.getItem(TOKEN_KEY))
    user: getItem(TOKEN_KEY),
  },
  mutations: {
    setUser(state, data) {
      state.user = data;
      // 为了防止刷新丢失,我们需要把数据备份到本地存储
      // window.localStorage.setItem(TOKEN_KEY, JSON.stringify(state.user))
      setItem(TOKEN_KEY, state.user);
    },
  },
  actions: {},
  modules: {},
});

三、封装 axios 请求模块

下载导入:npm install axios

// 封装 axios 请求模块
import axios from "axios";
import router from "@/router";
// axios.create 方法创建一个axios的实例
const request = axios.create({
  baseURL: "/localhost", // 接口的基准路径,改成自己的项目基地址
});
// 请求拦截器:是否注入token
request.interceptors.request.use(
  function (config) {
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);
// store文件中vuex和localstorage对token进行处理之后响应拦截器中统一处理 token 过期
// 处理流程:在axios拦截器中加入token刷新逻辑;用户token过期时,向服务器请求新的 token;旧token替换为新token;然后继续用户当前的请求
// 响应拦截器
request.interceptors.response.use(
  function (response) {
    return response;
  },
  async function (error) {
    console.dir(error);
    if (error.response && error.response.status === 401) {
      // 校验是否有 refresh_token
      const user = store.state.user;
      if (!user || !user.refresh_token) {
        router.push("/login");
        return;
      }
      // 如果有refresh_token,则请求获取新的 token
      try {
        const res = await axios({
          method: "PUT",
          url: "/admin/waterMeter/login", // 改成自己的项目的登录地址
          headers: {
            Authorization: `Bearer ${user.refresh_token}`,
          },
        });
        // 如果获取成功,则把新的 token 更新到容器中
        console.log("刷新 token  成功", res);
        store.commit("setUser", {
          token: res.data.data.token, // 最新获取的可用 token
          refresh_token: user.refresh_token, // 还是原来的 refresh_token
        });
        return request(error.config);
      } catch (err) {
        // 如果获取失败,直接跳转 登录页
        console.log("请求刷线 token 失败", err);
        router.push("/login");
      }
    }
    return Promise.reject(error);
  }
);
export default request;

四、在main.js文件内全局注册store、axios

import Vue from "vue";
import App from "./App.vue";
import router from "./router"; // 路由对象
import store from "./store"; // 管理用户token
import axios from "axios";
... ...
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount("#app");

五、新建api文件夹,存放接口文件

// 存储接口封装,用户相关的请求模块
import request from "@/utils/request.js";
// export const login = (user) => {
//   return request({
//     url: '', // 接口地址
//     method: 'POST', 'GET', // 请求方式
//     // 如果参数通过请求体来发(post),用data是请求体参数
//     // 如果参数通过请求行来发(get),用params是路径参数
//     data: user
//   })
// }
// 用户登录
export const login = (data) => {
  return request({
    method: "POST",
    url: "/admin/login",
    data,
  });
};
// 需要携带 token 获取数据时,携带登陆成功后存储在本地的token值
// 查询所有使用记录
export const listRecord = () => {
  return request({
    method: "GET",
    url: "/admin/record/listRecord",
    headers: {
      "X-Token": localStorage.getItem("X-Token"),
    },
  });
};
// 携带params参数,也是手动输入的值
export const others = (params) => {
  return request({
    method: "GET",
    url: "/admin/others",
    params,
  });
};

六、在组件页面内调接口拿数据

接口使用例子1

1. 登录接口的使用(同注册),在页面导入接口

// 调用登录接口
import { login } from '@/api/user'

2. 通过async await 来拿到用户输入的值,根据返回结果进行判断返回相应提示

async onSubmit (values) {
  // 手动输入提交的数据:登录、注册、修改密码等提交的值
  let { mobile: vcPhone, password: vcLoginpassword } = values
  const { data } = await login({ vcPhone, vcLoginpassword, })
  console.log(data);
  console.log("submit", values);
  if (data.code == "200") {
    this.$toast.success("登录成功");
    this.$router.push({ name: "shouye" });
  } else if (data.message == "没有注册,请先注册") {
    this.$toast.fail(data.message);
  } else if (data.message == "密码错误") {
    this.$toast(data.message);
  } else {
    this.$toast.fail('操作异常,请重试')
  }
  console.log("submit", values);
},
注意:mobile、password是用户在data里定义的值,这里需要将拿到的值赋给自己定义的。
      或者把data里的值改成和后端字段相同,此时可简写。
例如:
let { vcPhone, vcLoginpassword } = values
const { data } = await login({ vcPhone, vcLoginpassword, })

接口使用例子2

1. 通过接口获取数据进行渲染,这里把需要的接口解构出来

import { listRecord } from '@/api/user'

2. data定义需要渲染的数据(可与后端字段一致)

data () {
  return {
    recordFrom: {
      vcReadid: "",
      vcReaddate: "",
      vcCurrremainmoney: "",
    },
    list: [], // 存放所有使用记录数据
    loading: false,
    finished: false,
  };
},

3. 在方法里面调用接口,把拿到的数据放到一个自己定义的数组里面list

methods: {
  async getAllusedRecord () {
    try {
      const { data } = await listRecord()
      this.list = data
      this.loading = false; // 加载状态结束
      this.finished = true;
      // console.log(this.list);
    } catch (err) {
      this.$toast('获取使用记录失败')
    }
  },
},

4. 通过v-for渲染获取到的数据

<ul v-for="item in list" :key="item.name" :title="item">
  <li>
   编号:{{ item.vcReadid }}
   时间:{{ item.vcReaddate }}
   金额:{{ item.vcCurrremainmoney }}
  </li>
</ul>